configureStore는 Redux 스토어를 생성하는 함수로, Redux의 기본 createStore 함수보다 간편하게 스토어를 설정할 수 있도록 도와준다.
Redux Toolkit에서는 configureStore 함수를 사용하여 미들웨어 설정, Redux DevTools Extension 연결 등의 작업을 자동으로 처리할 수 있다.
configureStore 함수의 기본 구조는 다음과 같다:
import { configureStore } from "@reduxjs/toolkit";
const store = configureStore({
reducer: rootReducer, // rootReducer를 포함한 리듀서 객체
middleware: [
/* 미들웨어 배열 */
],
devTools: true, // Redux DevTools Extension을 사용할지 여부
});
configureStore 함수의 인자로 넣어주어야 하는 속성으로, 모든 리듀서를 합친 rootReducer를 전달한다.
미들웨어를 배열 형태로 전달하는 속성으로, Redux 미들웨어를 커스터마이징할 수 있습니다.
기본적으로 Redux Toolkit은 redux-thunk와 immutable-state-invariant 미들웨어를 자동으로 포함시킨다.
개발 환경에서 Redux DevTools Extension을 사용할지 여부를 설정하는 속성입니다. 기본값은 true로 설정되어 있다.
createSlice는 Redux Toolkit에서 리듀서와 관련된 로직을 간단하게 작성할 수 있도록 도와주는 함수다.
createSlice를 사용하면 리듀서 함수와 액션 생성자 함수가 함께 생성되며, 반복적인 코드를 최소화할 수 있다.
createSlice 함수의 기본 구조는 다음과 같습니다:
import { createSlice } from "@reduxjs/toolkit";
const slice = createSlice({
name: "sliceName", // Slice의 이름
initialState: {}, // 초기 상태
reducers: {
action1: (state, action) => {
// 리듀서 로직
},
action2: (state, action) => {
// 리듀서 로직
},
// 추가적인 액션과 리듀서 정의 가능
},
});
const { actions, reducer } = slice;
createSlice 함수의 인자로 넣어주어야 하는 속성으로, 생성되는 Slice의 이름을 정의한다.
Slice의 초기 상태를 정의하는 속성이다.
액션과 리듀서를 정의하는 속성으로, 객체의 키는 액션 이름이 되며, 값은 리듀서 함수가 된다.
createSlice 함수를 사용하면 액션 생성자 함수를 별도로 작성하지 않아도 되며, 액션 이름을 문자열로 사용하기 때문에 액션 이름의 중복을 방지할 수 있다.
또한, Slice에서 생성된 액션은 Redux Toolkit의 createAction 함수로 만든 것과 동일하게 사용할 수 있다.
이렇게 생성된 Slice는 reducer와 actions 객체를 반환하므로, 스토어의 리듀서에 바로 포함시켜서 사용할 수 있다.
configureStore 함수를 사용하여 Redux 스토어를 생성한다.
이때, reducer 속성에는 createSlice를 통해 생성한 toDos Slice를 넣어준다.
이렇게 하면 toDos Slice에서 생성된 액션과 리듀서가 스토어에 등록되어 상태를 업데이트할 수 있게 된다.
import { configureStore, createSlice } from "@reduxjs/toolkit";
// createSlice를 사용하여 toDos Slice를 생성
const toDos = createSlice({
name: "toDos",
initialState: [],
reducers: {
// add와 remove 액션을 생성하는 리듀서 함수를 정의
add: (state, action) => {
state.push({ text: action.payload, id: Date.now() });
},
remove: (state, action) =>
state.filter((toDo) => toDo.id !== action.payload),
},
});
// Redux 스토어 생성 및 configureStore 사용
const store = configureStore({
reducer: {
toDosReducer: toDos.reducer,
},
});
// toDos Slice에서 생성된 액션을 노출
export const { add, remove } = toDos.actions;
export default store;
To-Do 애플리케이션의 컴포넌트에서 Redux 스토어를 사용할 수 있다.
useSelector 훅을 사용하여 상태를 가져오고, useDispatch 훅을 사용하여 액션을 디스패치할 수 있다.
import React, { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { add, remove } from "../store";
function Home() {
// 1. useState를 사용하여 상태 관리
const [text, setText] = useState("");
// 2. useSelector를 사용하여 스토어의 상태를 가져옴
const toDos = useSelector((state) => state.toDosReducer);
// 3. useDispatch를 사용하여 액션 디스패치할 준비
const dispatch = useDispatch();
// 4. input 값 변경 시 호출되는 이벤트 핸들러
const onChange = (e) => {
setText(e.target.value);
};
// 5. 폼 제출 시 호출되는 이벤트 핸들러
const onSubmit = (e) => {
e.preventDefault();
// 6. add 액션 디스패치, 입력한 텍스트를 액션 페이로드로 전달
dispatch(add(text));
// 7. 입력한 텍스트 초기화
setText("");
};
// 8. 할일 항목 삭제 시 호출되는 이벤트 핸들러
const onRemove = (id) => {
// 9. remove 액션 디스패치, 삭제할 할일 항목의 id를 액션 페이로드로 전달
dispatch(remove(id));
};
return (
<>
<h1>To Do</h1>
{/* 10. 폼 제출 시 onSubmit 이벤트 핸들러 호출 */}
<form onSubmit={onSubmit}>
{/* 11. input 값 변경 시 onChange 이벤트 핸들러 호출 */}
<input type="text" value={text} onChange={onChange} />
<button>Add</button>
</form>
<ul>
{toDos.map((toDo) => (
<div key={toDo.id}>
<li>
{/* 12. 할일 항목과 삭제 버튼을 렌더링 */}
{toDo.text} <button onClick={() => onRemove(toDo.id)}>Remove</button>
</li>
</div>
))}
</ul>
</>
);
}
export default Home;
위 코드에서 useSelector를 사용하여 toDos 배열을 가져온 후, map 함수를 사용하여 각 할일 항목을 렌더링한다.
useDispatch를 사용하여 add와 remove 액션을 디스패치하여 상태를 업데이트한다.
각 할일 항목 옆에는 "Remove" 버튼을 누르면 해당 항목을 삭제하는 기능도 구현되어 있다.
이렇게 하면 Redux Toolkit을 사용하여 간단한 To-Do 애플리케이션의 상태 관리를 할 수 있다.
설명도 이상하고 코드도 이상한 글임에도 읽어주셔서 감사합니다. : )