COCO World
[React/리액트] Redux 사용방법과 구조 본문
1. Redux 설치
리액트에서 리덕스를 사용하기 위하여 패키지 설치를 해줘야 한다.
// 한번에 설치하기
yarn add redux react-redux
// 아래처럼 따로 설치하기
yarn redux
yarn react-redux
2. 폴더 구조 생성
[1] src 폴더 안에 redux 폴더를 생성
[2] redux 폴더 안에 config, modules 폴더를 생성
[3] config 폴더 안에 configStore.js 파일을 생성
각각 폴더와 파일의 역할
- redux : 리덕스와 관련된 코드를 모두 모아 놓을 폴더
- config : 리덕스 설정과 관련된 파일들을 놓을 폴더
- configStore : '중앙 state 관리소'인 Store를 만드는 설정 코드들이 있는 파일
- modules : 우리가 만들고 필요한 State들을 모아둔 파일. 이것이 곧 하나의 모듈.
3. 설정 코드 작성
- src/configStore.js
import { createStore } from "redux";
import { combineReducers } from "redux";
/*
1. createStore()
리덕스의 가장 핵심이 되는 스토어를 만드는 메소드(함수) 입니다.
리덕스는 단일 스토어로 모든 상태 트리를 관리한다고 설명해 드렸죠?
리덕스를 사용할 시 creatorStore를 호출할 일은 한 번밖에 없을 거예요.
*/
/*
2. combineReducers()
리덕스는 action —> dispatch —> reducer 순으로 동작한다고 말씀드렸죠?
이때 애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생합니다.
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어줍니다.
*/
const rootReducer = combineReducers({});
const store = createStore(rootReducer);
export default store;
- index.js
// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
//App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
<Provider store={store}>
<App />
</Provider>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
3. Redux 모듈의 구성요소 살펴보기
[1] initialState : 초기 상태값
단어 그대로 초기 상태값이다. 즉, 어떤 State의 초기값을 정해주는 것이다.
우리가 useState를 사용했을 때 괄호 안에 초기값을 지정해주는 것과 같은 이치로 이해하자
// 초기값이 0
const initialState = 0;
// 초기값이 0이 있는 배열
const initialState = [0];
// 초기값이 number = 0, name = '석구'인 객체
const initialState = {
number: 0,
name: '석구'
};
[2] Reducer = 변화를 일으키는 함수
우리가 useState()를 사용할 때, 상태값을 변경하기 위해 setState()를 사용하는 것처럼, 리듀서가 이 역할을 해준다.
// src/redux/modules/counter.js
// counter 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
export default counter; // 여기
[3] Reducer 함수 모듈을 스토어에 연결하기
여태까지 모듈파일에서 초기 상태값과 리듀서 함수를 작성했다. 아직까지 모듈과 스토어가 각각 따로 분리되어 있는 상태이기 때문에
우리가 만든 State를 스토어에서 꺼낼 수 없다. 이제 우리가 만든 모듈을 스토어에 연결 시켜줘야 한다.
// src/redux/modules/config/configStore.js
// 원래 있던 코드
import { createStore } from "redux";
import { combineReducers } from "redux";
// 새롭게 추가한 부분
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter: counter, // <-- 새롭게 추가한 부분
});
const store = createStore(rootReducer);
export default store;
4. 스토어와 모듈 연결 확인하기
[1] useSelector = 스토어 조회
우리가 생성한 모듈을 스토어에 잘 연결했는지 확인하는 방법은 컴포넌트에서 스토어를 직접 조회하면 된다.
컴포넌트에서 Redux Store를 조회하고자 할때는 useSelector라는 react-redux hook을 사용해야 한다.
// 1. store에서 꺼낸 값을 할당 할 변수를 선언합니다.
const number =
// 2. useSelector()를 변수에 할당해줍니다.
const number = useSelector()
// 3. useSelector의 인자에 화살표 함수를 넣어줍니다.
const number = useSelector( ()=>{} )
// 4. 화살표 함수의 인자에서 값을 꺼내 return 합니다.
// 우리가 useSelector를 처음 사용해보는 것이니, state가 어떤 것인지 콘솔로 확인해볼까요?
const number = useSelector((state) => {
console.log(state)
return state
});
[2] App.js
// src/App.js
import React from "react";
import { useSelector } from "react-redux"; // import 해주세요.
const App = () => {
const counterStore = useSelector((state) => state); // 추가해주세요.
console.log(counterStore); // 스토어를 조회해볼까요?
return <div></div>;
}
export default App;
4. Redux의 흐름
[1] View에서 액션이 일어난다.
[2] dispatch에서 action이 일어나게 된다.
[3] action에 의한 reducer 함수가 실행되기 전에 middleware가 작동한다.
[4] middleware 에서 명령내린 일을 수행하고 난뒤, reducer 함수를 실행한다.
[5] reducer 의 실행결과 store에 새로운 값을 저장한다.
[6] store의 state에 subscribe 하고 있던 UI에 변경된 값을 준다.
** 흐름 정리 **
- 액션 객체란, 반드시 type이란 key를 가져야 하는 객체이며, reducer로 보낼 '명령'이다.
- 디스패치란, 액션 객체를 reducer로 보내는 '전달자' 함수 이다.
- 리듀서란, 디스패치를 통해 전달받은 액션객체를 검사하고, 조건이 일치했을 때 새로운 상태값을 만들어내는 '변화를 만들어내는' 함수이다.
- 디스패치(dispatch)를 사용하기 위해서는 useDispatch()라는 훅을 사용한다.
- 액션객체 type의 value는 대문자로 작성한다.
5. Redux의 Refactoring (action creators, action values)
[1] payload
: 리듀서에게 액션 객체를 보낼 때, 목적어가 생긴 경우, 목적어도 액션 객체에 담아서 같이 보내야한다. 이럴 때 사용한다.
- 리듀서로 보내는 액션객체에 어떤 정보를 담아 같이 보내고자 한다면 payload를 사용하자
- payload는 Action Creator를 생성할 때 매개변수에 자리에서 받을 준비를 하고, 반환하는 액션객체에 payload라는 key와 받은 매개변수를 value로 하여 구현한다.
- 리듀서에서 payload를 사용하고 할 때는 action.payload로 사용할 수 있다
[2] Action Creator
: 만약 우리가 액션객체의 value를 변경할 일이 생긴다면 코드상으로 4군데에서 변경해야 한다. 그치만 대규모 프로젝트가 될 경우,
하드 코딩이 곤란하기 때문에 액션객체를 한 곳에서 관리할 수 있도록 '함수'와 액션 value를 상수로 만들어야 한다.
- 액션객체를 만드는 함수를 Action Creator라고 한다.
- Action Creator는 모듈 파일안에서 생성된다.
- 액션객체의 type value로 상수로 생성해서 관리한다.
- Action Creator를 사용하면, 여러가지 문제점을 해소할 수 있다.
'Front-End > React' 카테고리의 다른 글
[리액트/React] JSX(개념, 문법, 특징)에 대해 알아보자. (0) | 2023.05.29 |
---|---|
[React/리액트] index.js와 index.html에 대하여 (0) | 2023.05.29 |
[React/리액트] React Hooks - useState / useEffect / useRef / useContext (0) | 2023.02.16 |
[React/리액트] styled-components와 CSS-in-Js (0) | 2023.02.16 |
[React/리액트] 컴포넌트(Component)에 대하여 (0) | 2023.02.09 |