갑자기 불어난 폴더와… 이리갔다가 저리갔다가 하는게 도무지 정리가 안 되어서 강의 중지하고 정리해야겠다 싶었다… 내 방식대로 정리해보자 싶어서 편하게(?) 쓴거라 말투도 기존 글과 다를지도…ㅎ
아무튼 이 글은 << 내 입맛대로 정리해보는 Redux 👊🏻👊🏻👊🏻👊🏻 >> 이고.. 틀린거 있으면 (누군가 본다면) 댓글로 알려주쉐이~
Redux 정리 (redux 및 reducer 만들기)
config
: 이름에서 알 수 있듯이 ‘설정’ 과 관련된 모든 것이 들어있는 폴더
configStore
: 리덕스는 중앙 관리소가 있다 = store
!
이 Store
를 만드는 파일인데 설정담당 config파일 안에 있으니까 Store 만드는 ‘설정’이 담긴 파일이다.
modules
: 우리가 만드는 State
가 있는 공간
configStore에서 할 일
✋ configStore
는 뭐다? Store
를 만드는 '설정'을 모아두는 곳! 따라서 Store 설정
을 해주고 export해주는 곳!
rootReducer
는 조각난 리듀서들을 모아줄 combineReducer
createStore()
createStore
안에 리듀서가 담긴 rootReducer
를 담아주고 최종적으로 이 store
를 export한다.
import { createStore } from "redux";
import { combineReducers } from "redux";
/*
combineReducers()
애플리케이션이 복잡해지게 되면 reducer 부분을 여러 개로 나눠야 하는 경우가 발생합니다.
combineReducers은 여러 개의 독립적인 reducer의 반환 값을 하나의 상태 객체로 만들어줍니다.
*/
const rootReducer = combineReducers({});
const store = createStore(rootReducer);
export default store;
열심히 만든 store 넌 최상위 컴포넌트(ex.Main.jsx / App.jsx)에서 일해라
// 원래있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
만드는 놈 따로 쓰는 놈 따로임…ㅎ
config
폴더에서 열심히 만든 Store
를 사용하기 위해 제일 최상단 컴포넌트로 import 해오자
import store from "./redux/config/configStore";
불러온 Store
는 또 곱게 오지 않아서 Provider
라는 놈이 안내를 해줘야 따라온다.
우리는 App컴포넌트 안에 있는 모-든 애들이 store에 접근해서 뽑아먹을 수 있게 하기 위해 Provider를 아래 코드처럼 감싸준다.
⭐️ 주의할 것: Provider는 무조건 store를 써줘야한다! (안 쓰면 에러나용~)
<Provider store={store}>
<App />
</Provider>
zㅏ! config
에서 할 일은 끝났고 이제 내 기준 깐깐징어였던 모듈을 정리해보자
모듈은 State 그룹!
, State
는? 변경되는 값
들이다 > 리덕스에서 변경하는거 뉘기야?! = reducer
모듈에서 reducer 맨드는구나~~ 하기
react state 만들때 우리 초기값 줬던거 기억 나는 살암? 모듈은 state
그룹이니까 똑같이 초기값이 필요하다.
초기값에는 원시데이터, 객체, 배열 모두 다 됨다.
// 초기값이 0
const initialState = 0;
// 초기값이 0이 있는 배열
const initialState = [0];
// 초기값이 number = 0, name = '리덕스놈'인 객체
const initialState = {
number: 0,
name: '리덕스놈'
};
앙딱정 reducer는 함수다!
reducer
는 2개의 인자가 필요한데 1) state 2) action 이다.
보통 state에는 우리가 맨 처음 만들었던 초기값을 할당해주고 action 객체에서 필요한 걸 꺼내서 사용하는 방식이다.
// src/redux/modules/counter.js
// counter 리듀서
const counter = (state = initialState, action) => {
switch (action.type) {
default:
return state;
}
};
export default counter;
잘 만든 이 counter라는 함수 잘 내보내주자!
(예시 코드가 counter라서 counter를 내보낸것, todo를 만들었다면 todo 내보내기!)
지금까지 한 일이 뭔디여
config
폴더에서 Store
만들기 / modules
폴더에서 reducer
만들기
아까 조각난 reducer
를 combineReducer
해줬던거 기억나는 살암?
좀 전에 reducer
조각 하나를 만들었으니까 이걸 합쳐주는 combineReducer
한테 연결해서 이거 모아달라고 말해야한다.
그럼 이제 우리가 만든 reducer
를 쓸 수 있도록 combineReducer
찾아서 연결해주자!
// src/redux/config/configStore.js
// 원래 있던 코드
import { createStore } from "redux";
import { combineReducers } from "redux";
// 모듈에서 만든 reducer 함수를 불러오고
import counter from "../modules/counter";
const rootReducer = combineReducers({
counter: counter, // reducer 조각 모아달라고 낑겨넣기
});
const store = createStore(rootReducer); // 그럼 store에 reducer가 들어있겟쥬?
export default store;
끝났다고 생각하지마!!! 이제부터 시작이니ㄲㅏ
또 이런거 잘 연결됐는지 확인하고 싶어하는 그런 맘… 그래서 무좍건 콘솔찍어보고 그러자네?
그래서 이제 뭘 할거냐면 우리가 만든 모듈이 스토어에 잘 연결됐는지 확인할거예여
자 이제 useSelector
를 써봅시다.
useSelector
는 Store
가 잘 연결되어있는지 “컴포넌트에서 스토어를 직접 조회”할 때 쓰는 훅이다.
⭐️ 훅!을 사용하는거니까 import {useSelector} 하는거 잊지 말기!!
// 1. store에서 꺼낸 값을 할당 할 변수 선언
const number =
// 2. useSelector()를 변수에 할당해줍니다.
const number = useSelector()
// 3. useSelector의 인자에 화살표 함수를 넣어줍니다.
const number = useSelector( ()=>{} )
// 4. 화살표 함수의 인자에서 값을 꺼내 return 합니다.
const number = useSelector((state) => {
console.log(state)
return state
});
내 입맛대로 정리해보면
// src/App.js
import React from "react";
import { useSelector } from "react-redux"; // useSelector 훅 import
const App = () => {
const counterReducer = useSelector((state) => state); // 추가해주세요.
console.log("🚀 counterReducer:", counterReducer); // 콘솔로 확인
return <div></div>;
}
export default App;
useSelector
할당state
추가콘솔을 확인해보면 객체 안에 우리가 만든 counter 모듈이 들어있다.
✅ state 확인하면 이 안에 있는 모든 값이 나온다.
이제 우리는 어!떤! 컴포넌트에서도 접근할 수 있는 Store
를 가지게 되었다.
아까 counter 모듈을 만들 때 넣었던 counter를 쓰고 싶다면 아래 코드처럼 쓰면 된다.
const counterReducer = useSelector((state) => {
return state.counter;
});
콘솔창 확인
더 디테일하게 뽑아서 사용하기
const number = useSelector(state => state.counter.number); // 0
나름 간단하게 정리한다고 해봤는데 또 길어진 느낌이다.
redux
폴더에는 '설정'담당 : config
폴더 / state
그룹 담당 : modules
폴더가 있다.
createStore()
로 store
를 만들고, combineReducers({})
에 의해 reducer 조각이 합쳐진 rootReducer
변수를 넣어준다. (!! store 설정 완 )
최상단 컴포넌트 (ex. App 컴포넌트) 에 Provider
로 감싸준다. store
넣어주기!
초기값
, reducer
함수 그리고 이 함수를 export 한 모듈을 만들어준다.
리듀서 함수가 받는 인자 state에는 초기값 할당, action 객체
를 만든다.
만든 리듀서를 combineReducer
에 넣어주고 useSelector
훅으로 연결하여 사용한다.