- Redux, RTK 사용법 정리 - (2)2025년 02월 10일
- redpome
- 작성자
- 2025.02.10.:54
https://redpome.tistory.com/25
Redux, RTK 사용법 정리 - (1)
머릿속에 남을려면 내가 정리를 해야한다. 사용법을 익힐겸 정리해보자.Redux 개념Context API를 통해서 컴포넌트에서 전역으로 상태를 관리하는 방법을 학습했었다. Context API는 Provider로 감싸고 컴
redpome.tistory.com
위의 사용법에 이어서 정리한다.
이번 포스팅에서는 다음의 일들을 정리하자
- Redux 사이클
- Redux -> Redux Tool kit으로 리팩터링
출처 : https://ko.redux.js.org/tutorials/essentials/part-1-overview-concepts State : Redux에서 Store에 저장된 상태를 가리키고 읽기 전용의 immutable 이다. Reducer를 통해 state를 업데이트한다.
View : 현재의 State를 렌더링한다. 당연히 State의 변경이 일어나면 리렌더링이 발생한다.
Actions : 사용자의 애플리케이션과의 상호작용으로 State를 변경한다.
위와 같이 Redux는 State -> View -> Actions의 사이클을 가진다.
https://github.com/PomegranateBlue/st-timeattack
GitHub - PomegranateBlue/st-timeattack: 2025년 2월 10일
2025년 2월 10일. Contribute to PomegranateBlue/st-timeattack development by creating an account on GitHub.
github.com
위의 깃허브 코드를 통해 redux의 사용방법을 다시 한 번 살펴보자
redux라는 디렉토리를 생성하고 다음과 같이 파일 구조를 생성했다.
store를 위한 configStore부터 살펴보자
import { createStore } from "redux"; //Redux 스토어를 생성하는 함수 import { combineReducers } from "redux"; //여러개의 리듀서를 하나로 합치는 함수 import messageReducer from "../modules/messageModule"; //모듈에서 가져온 리듀서 const rootReducer = combineReducers({ /*로직을 작성 */ messageModule: messageReducer, //모듈에서 가져온 리듀서를 명칭할 때는 -module을 붙이기 //컴포넌트에서 사용 시에는 해당 모듈의 리듀서를 사용하는 것임을 명시 //state.messageModule.message }); const store = createStore(rootReducer); export default store;
나름대로의 Redux 사용방법을 위해 store에서 module을 불러올 때에는 불러온 모듈의 사용에 있어서 -module을 붙여주기로 했다.
위의 코드는 스토어를 생성하고, 리듀서를 합치고 불러온 모듈에서의 리듀서 사용을 messageModule이라는 이름으로 명시한다.
import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import "./index.css"; import App from "./App.jsx"; import { Provider } from "react-redux"; import store from "./redux/config/configStore.jsx"; createRoot(document.getElementById("root")).render( <StrictMode> <Provider store={store}> <App /> </Provider> </StrictMode> );
main.jsx에서 Provider를 호출하고, store를 주입하였다. 상태를 관리하는 store를 Provider로 주입함으로 컴포넌트에서 모듈에서정의한 Reducer를 호출해서 사용할 수 있다.
main.jsx 파일에서는 React Redux의 Provider 컴포넌트를 사용해 Redux store를 애플리케이션 전체에 주입하고, 하위 컴포넌트들은 Provider를 통해 전달받은 store에 접근할 수 있으며, store에 정의된 리듀서를 호출하여 상태를 관리할 수 있다.모듈같은 경우는 다음과 같이 정의하고 있다.
const initialState = { message: "", }; const SET_MESSAGE = "SET_MESSAGE"; export const setMessage = (message) => ({ type: SET_MESSAGE, payload: message, }); const messageReducer = (state = initialState, action) => { switch (action.type) { case SET_MESSAGE: return { ...state, message: action.payload }; default: return state; } }; export default messageReducer;
리듀서를 먼저 설명하자면 Actions에 정의된 동작을 수행하는 함수라 할 수 있다. 사용자의 입력을 받아 화면에 렌더링하기 위해 messageReducer라는 리듀서를 정의하고, state, action을 인자로 받아 현재 state의 값을 action.type에 정의한 동작을 수행하도록했다.
위의 코드에서 주요 내용을 정리하자면 다음과 같다.
- setMessage : SET_MESSAGE에 해당하는 타입의 action을 받으면 인자로 받은 message를 payload로 포함한 객체로 반환하는 Action Creator
- messageReducer : action.type에 따라 해당 action에 따른 동작을 수행, 현재 위의 코드에서 SET_MESSAGE라는 액션 타입은 action.payload로 받은 내용으로 state를 업데이트
import { useDispatch } from "react-redux"; import { setMessage } from "../redux/modules/messageModule"; function StateControl() { const [inputValue, setInputValue] = useState(""); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); dispatch(setMessage(inputValue)); setInputValue(""); }; const handleReset = () => { setInputValue(""); dispatch(setMessage("")); };
사용자의 입력을 처리하는 컴포넌트에서 react-redux에서 제공하는 useDispatch 함수를 호출하여 dispatch 함수를 가져온다.
그리고 모듈로부터 불러온 setMessage 액션 생성자를 사용한다.
사용자가 입력 필드에 텍스트를 입력한 후 폼을 제출하면, 해당 입력값(inputValue)을 setMessage 함수에 전달하여 액션 객체를 생성한다. 이후, 이 액션 객체를 dispatch 함수를 통해 Redux store에 전달하면, store 내부의 리듀서가 전달받은 액션에 따라 상태를 업데이트한다.
흐름을 정리하자면 다음과 같다.
액션 생성자 호출 → 액션 객체 생성 → dispatch 함수 호출 → Redux store로 전달 → 리듀서에서 상태 업데이트
import { useSelector } from "react-redux"; function Level1() { return ( <LevelContainer> <h3>Level 1</h3> <Level2 /> </LevelContainer> ); } function Level2() { return ( <LevelContainer> <h3>Level 2</h3> <Level3 /> </LevelContainer> ); } function Level3() { return ( <LevelContainer> <h3>Level 3</h3> <MessageDisplay /> </LevelContainer> ); } function MessageDisplay() { const message = useSelector((state) => state.messageModule.message); return ( <MessageDisplayWrapper> <h3>메시지 표시 영역</h3> <p>{message || "아직 메시지가 없습니다..."}</p> </MessageDisplayWrapper> ); }
Level1 => Level2 => Level3
원래는 위의 순서대로 Props를 전달하고 사용자로부터 받은 message를 최종적으로 Level3 컴포넌트에서 MessageDisplay 컴포넌트를 통해 화면에 렌더링하지만, Redux에 의해 무의미한 컴포넌트의 경로를 거칠 필요가 없어졌다.모듈에서의 초기 상태로 정의한 initialState에서 message는 state.messageModule.message를 호출하여 Store에서 message 값을 가져온다. 이렇게 가져온 값은 초기 상태, 또는 리듀서에 의해 변경된 값이다.
정리
Redux는 사용방법을 익히는 것에 집중하자.
- Reducer, initialState 정의
- module 파일 생성 후 Reducer 정의
const initialState = { message: "", }; const messageReducer = (state = initialState, action) => { switch (action.type) { case SET_MESSAGE: return { ...state, message: action.payload }; default: return state; } }; export default messageReducer;
- Action, Action Creator 정의
- module에서 상태 변경을 위한 액션, 액션 생성자 정의
export const SET_MESSAGE = "SET_MESSAGE"; export const setMessage = (message) => ({ type: SET_MESSAGE, payload: message, });
- Store 생성후 리듀서 연결
import { combineReducers } from "redux"; import messageReducer from "./messageReducer"; const rootReducer = combineReducers({ messageModule: messageReducer, // '-모듈 : -리듀서' 라고 짓자 }); export default rootReducer;
4. Provider를 통해 Store 주입
import { Provider } from "react-redux"; import App from "./App"; import store from "./redux/store"; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById("root") );
5. 컴포넌트에서 상태 구독, 액션 디스패치
import { useState } from "react"; import { useDispatch } from "react-redux"; // 리듀서로 액션을 전달 import { setMessage } from "../redux/actions"; const StateControl = () => { const [inputValue, setInputValue] = useState(""); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); dispatch(setMessage(inputValue)); setInputValue(""); }; const handleReset = () => { setInputValue(""); dispatch(setMessage("")); };
'React' 카테고리의 다른 글
Redux, RTK 사용법 정리 - (1) (0) 2025.02.07 React hooks(1) (0) 2025.01.27 투두 리스트 복기 (1) 2025.01.24 개인과제 회고 - 올림픽 메달 기록 (0) 2025.01.22 리액트 리스트 추가 및 생성 (1) 2025.01.22 다음글이전글이전 글이 없습니다.댓글