💻오늘 배운 내용
1] Redux
전역 상태관리 라이브러리
“중앙 state 관리소”를 사용할 수 있게 도와주는 패키지이다.
useState로 생성한 State는 Local State이고, 리덕스에서 생성한 State는 Global State라고한다.
useState로 상태를 관리한 경우, 어떤 State를 컴포넌트 간에 공유하고자 할때 반드시 부모에서 자식으로
한방향 정보전달만 가능했기 때문에 중간에 불필요한 과정이 발생하기도 했다.(props drilling)
따라서 리덕스는 useState를 통해 상태를 관리했을 때 발생하는 이러 불편함을 일부 해소시켜준다.
동작원리
리덕스의 동작원리는 액션, 디스패치, 리듀서로 이루어진다.
Action
type 필드를 가진 자바스크립트 객체다. 쉽게 생각해서, 어떤 일이 일어났는지를 설명하는 이벤트라고 생각하셔도 무방하다. 보통, type과 payload 프로퍼티를 가지며 type은 어떤 액션인지를 나타내며, payload는 데이터를 담는다.
액션은 dispatch를 통해 reducer 함수로 보내지며 기존의 state를 기반으로 새로운 state를 생성한다.
(불변성을 지키는 것이 redux의 원칙)
Dispatch
redux에서 dispatch는 액션을 reducer로 전달한다.
즉, state를 업데이트하는 유일한 방법은 store.dispatch 함수를 호출하는 것. 이벤트를 발생시키는 역할을 한다.
Reducer
reducer함수는 기존의 state와 action을 받아서 새로운 state를 만들어내는 함수. 이벤트 리스너같은 역할.
root reducer
redux에서는 오직 하나의 리듀서만이 존재한다.
유지 보수를 위해 여러 개의 리듀서를 만든 뒤에 하나의 루트 리듀서로 병합하여 사용하는 형태.
2] Redux 설치 및 셋팅
yarn add redux react-redux
redux와 react-redux 2개의 패키지를 설치한다.
react-redux는 리덕스를 리액트에서 사용할 수 있도록 서로 연결시켜주는 패키지다.
1. src 폴더 안에 redux 폴더를 생성
2. redux 폴더 안에 config, modules 폴더를 생성
3. config 폴더 안에 configStore.js파일을 생성
redux : 리덕스 관련 코드를 모두 몰아넣음
config : 리덕스 설정 관련 파일 전부
configStore : 중앙 state 관리소 -> 설정 코드 (.js)
modules : state의 그룹! 예) TodoList. todo.js
configStore.js 파일은 아래와 같이 설정해준다.
import { createStore } from "redux";
import { combineReducers } from "redux";
const rootReducer = combineReducers({});
const store = createStore(rootReducer);
export default store;
1. createStore()
리덕스의 가장 핵심이 되는 스토어를 만드는 메소드(함수).
리덕스는 단일 스토어로 모든 상태 트리를 관리한다. 리덕스를 사용할 시 creatorStore를 호출할 일은 한 번밖에 없을 것.
2. combineReducers()
리덕스는 action —> dispatch —> reducer 순으로 동작한다.
이때 애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생하는데
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어준다.
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] 모듈 만들기 및 스토어에 연결
modules 폴더에 js파일을 생성한다. 여기에 입력한 데이터를 state로 사용할 것이다.
// src/modules/counter.js
// 초기 상태값
const initialState = {
number: 0,
};
// 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
// 모듈파일에서는 리듀서를 export default 한다.
export default counter;
카운터 app을 예시로 만들어 볼거라서 초기값을 간단하게 숫자로 설정해 주었다.
리듀서는 state와 action을 인자로 받는다.
state에는 설정해둔 초기 상태값을 할당해주고,
action에는 type과 payload가 객체 형태로 존재 하는데 일단 payload 없이 type만 가지고 예시를 들어보려 한다.
모듈을 만들었으면 이제 스토어에 연결해주어야 하는데 config폴더의 configStore.js파일에
만든 모듈파일을 import 해준다.
// 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;
rootReducer 객체 안에 counter를 추가해준다.
이는 모듈을 추가할 때마다 똑같이 import하고 rootReducer 객체 안에 추가해주면 된다.
4] 컴포넌트에서 사용하기
이제 이 스토어의 값을 컴포넌트에서 사용하려면 useSelector라는 Hook을 사용해야한다.
// 1. store에서 꺼낸 값을 할당 할 변수를 선언.
const number =
// 2. useSelector()를 변수에 할당.
const number = useSelector()
// 3. useSelector의 인자에 화살표 함수를 넣어준다.
const number = useSelector( ()=>{} )
// 4. 스토어에 저장되어 있는 카운더가 조회된다. // {number: 0}
const number = useSelector((state) => state.counter);
화살표 함수에서 꺼낸 state라는 인자는 현재 프로젝트에 존재하는 모든 리덕스 모듈의 state.
만약 컴포넌트에서 counter 모듈의 number라는 값을 사용하고자 한다면 아래처럼 꺼내서 사용하면 된다.
const number = useSelector(state => state.counter.number); // 0
📋레퍼런스
https://velog.io/@y1andyu/Redux-Redux-thunk-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC
'내일배움캠프 > Today I Learned' 카테고리의 다른 글
[TIL 2023.06.23] React Router Dom (hooks, Dynamic route, useParam) (0) | 2023.06.23 |
---|---|
[TIL 2023.06.22] Redux에 대하여 2 (Action Creator, Payload, useDispatch, Ducks 패턴) (0) | 2023.06.23 |
[TIL 2023.06.20] React Hooks useContext / useCallback / useMemo (0) | 2023.06.21 |
[TIL 2023.06.19] React Styled components / useEffect / useRef (0) | 2023.06.20 |
[TIL 2023.06.16] 후발대 과제 / React counter app 만들기 (0) | 2023.06.19 |