(1) 설치
yarn add redux react-redux
아래와 같은 의미
yarn add redux
yarn add react-redux
(2)폴더 구조 생성하기

redux : 리덕스와 관련된 코드를 모두 모아 놓을 폴더
config : 리덕스 설정과 관련된 파일들을 놓을 폴더
configStore : “중앙 state 관리소" 인 Store를 만드는 설정 코드들이 있는 파일
modules : 우리가 만들 State들의 그룹이라고 생각. 예를 들어 투두리스트를 만든다고 한다면, 투두리스트에 필요한 state들이 모두 모여있을 todos.js를 생성하게 될텐데 이 todos.js 파일이 곧 하나의 모듈이 됨
(3)설정 코드 작성
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;
// 원래부터 있던 코드
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();
(1)모듈 만들기
// src/redux/modules/counter.js
// 초기 상태값
const initialState = {
number: 0,
};
// 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
// 모듈파일에서는 리듀서를 export default 함.
export default counter;
(2)모듈의 구성요소
// src/redux/modules/counter.js
// counter 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
export default counter; // 여기
state에 initialState를 할당해줘야함!
// src/redux/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;
=> 스토어와 모듈이 연결됨!
(3)스토어와 모듈 연결 확인하기
// 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
});
// 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;
=> 화살표함수에서 꺼낸 state라는 인자는 현재 프로젝트에 존재하는 모든 리덕스 모듈의 state!
=> 만약 컴포넌트에서 number라는 값을 사용하고자 한다면
const number = useSelector(state => state.counter.number); // 0
(4) counter.js 모듈의 state 수정 기능 만들기(+1 기능 구현)
// 예시 코드
//number에 +1 을 하는 액션 객체
{ type : "PLUS_ONE" };
=> 리더스 모듈에 있는 state를 변경하기 위해서는 그에 해당하는 액션 객체 모두를 만들어줘야 함.
useDispatch 사용// src/App.js
import React from "react";
import { useDispatch } from "react-redux"; // import 해주세요.
const App = () => {
const dispatch = useDispatch(); // dispatch 생성
return (
<div>
<button>+ 1</button> {/* 버튼을 하나 추가해주세요. */}
</div>
);
};
export default App;
그리고 dispatch를 사용할 때 ()안에 액션객체를 넣어주면 됨.
// src/App.js
import React from "react";
import { useDispatch } from "react-redux"; // import 해주기!
const App = () => {
const dispatch = useDispatch(); // dispatch 생성
return (
<div>
<button
// 이벤트 핸들러 추가
onClick={() => {
// 마우스를 클릭했을 때 dispatch가 실행되고, ()안에 있는 액션객체가 리듀서로 전달됨.
dispatch({ type: "PLUS_ONE" });
}}
>
+ 1
</button>
</div>
);
};
export default App;
// src/redux/modules/counter.js
// 초기 상태값
const initialState = {
number: 0,
};
// 리듀서
const counter = (state = initialState, action) => {
console.log(action); // 여기에 console.log(action) 추가
switch (action.type) {
default:
return state;
}
};
// 모듈파일에서는 리듀서를 export default
export default counter;
// src/modules/counter.js
// 초기 상태값
const initialState = {
number: 0,
};
// 리듀서
const counter = (state = initialState, action) => {
console.log(action);
switch (action.type) {
// PLUS_ONE이라는 case를 추가.
// 여기서 말하는 case란, action.type을 의미.
// dispatch로부터 전달받은 action의 type이 "PLUS_ONE" 일 때
// 아래 return 절이 실행.
case "PLUS_ONE":
return {
// 기존 state에 있던 number에 +1을 더함.
number: state.number + 1,
};
default:
return state;
}
};
// 모듈파일에서는 리듀서를 export default
export default counter;
// src/App.js
import React from "react";
import { useDispatch, useSelector } from "react-redux";
const App = () => {
const dispatch = useDispatch();
// 👇 코드 추가
const number = useSelector((state) => state.counter.number);
console.log(number); // 콘솔 추가
return (
<div>
{/* 👇 코드 추가 */}
{number}
<button
onClick={() => {
dispatch({ type: "PLUS_ONE" });
}}
>
+ 1
</button>
</div>
);
};
export default App;
:)