티스토리 뷰
Redux 공식문서에서 Redux Toolkit 사용을 공식적으로 적극 추천한다. 기존 Redux에서 작업을 단순화하고, 흔한 실수를 방지하여 Redux 어플리케이션을 더 쉽게 만들 수 있도록 한다.
기존의 Redux를 React, vanillaJS에서 사용하는 방법은 각각 다음의 포스팅에서 확인할 수 있다.
createAction
function createAddAction(text){
return {
type: 'add',
payload: text
}
}
const action = createAddAction('hello')
우리는 위와 같이 액션 생성자를 정의해주었다. 액션마다 function, return, type:, payload: 등을 입력해주는 것은 귀찮고 비효율적인 일이다. Redux Toolkit에서는 이러한 반복적인 작업을 해주지 않고 다음과 같이 두 줄만으로 원하는 action을 생성할 수 있다.
const actionAddCreator = createAction('add');
const action = actionAddCreator('hello'); // { type: 'add', payload: 'hello' }
console.log(actionAddCreator); // function
console.log(actionAddCreator.type); // 'add'
console.log(actionAddCreator()); // { type: 'add', payload: undefined }
createReducer
createReducer을 사용하는 방법은 Redux 공식문서를 참고할 수 있다. 그 중에서 소개할 것은 위에서 살펴본 createAction과 결합해서 사용할 수 있는 아주 간편한 방법이다.
const addToDo = createAction('add');
const deleteToDo = createAction('delete');
const reducer = createReducer([], {
[addToDo]: (state, action) => { state.push(action.payload) }
[deleteToDo]: (state, action) => state.filter(toDo => toDo !== action.payload)
};
// first argument [] is initialState.
// key of second argument object is action-name created by createAction.
// createReducer has two options if state is not primitive value,
// 1. just mutate state like [addToDo]
// 2. return new state like [deleteToDo]
configureStore
configureStore은 더 나은 개발자 경험을 위해 createStore에 몇 가지 기본 설정을 추가해놓은 함수이다. 그래서 configureStore로 생성한 store은 추가작업을 해주지 않아도 자동으로 Redux developer tools를 사용할 수 있다.
configureStore의 전달인자로 reducer 프로퍼티를 가진 객체를 전달해주며, 다음과 같이 하나의 상태만 다룰 수도 있고 여러 개의 상태를 다룰 수 있다.
import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducers'
const store = configureStore({
reducer: rootReducer,
})
export default store
import { configureStore } from '@reduxjs/toolkit'
import usersReducer from './usersReducer'
import postsReducer from './postsReducer'
const store = configureStore({
reducer: {
users: usersReducer,
posts: postsReducer,
},
})
export default store
createSlice
createSlice로 한 번에 reducer와 action을 생성할 수 있다. 아예 action을 정의하거나 action 생성자를 만들지 않는다. reducer만 정의해주면 createSlice가 actions와 reducer를 제공한다.
// counterSlice.js
import { createSlice } from "@reduxjs/toolkit";
const counterSlice = createSlice({
name: "counter",
initialState: { value: 0 }, // not primitive value
reducers: {
add: (state) => {
state.value++;
},
minus: (state, action) => {
state.value--;
},
setDefault: (state, action) => {
state.value = action.payload;
},
},
}); // counterSlice has reducer and actions like below
export const { add, minus, setDefault } = counterSlice.actions; // actionCreator: (payload) => { type: name/actionCreator, payload }
export default counterSlice.reducer;
// store.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";
const store = configureStore({ reducer: { counter: counterReducer } }); // useSelector( state => state.counter ) 으로 사용
export default store;
// App.js
import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { add, minus, setDefault } from "./counterSlice"; // ActionCreators
function App() {
const counter = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
const onAddClick = () => {
dispatch(add());
};
const onMinusClick = () => {
dispatch(minus());
};
const onSetDefaultClick = () => {
dispatch(setDefault(0));
}; // payload 0
return (
<div>
<button onClick={onAddClick}>add</button>
<span>{counter}</span>
<button onClick={onMinusClick}>minus</button>
<button onClick={onSetDefaultClick}>reset</button>
</div>
);
}
export default App;
combinedReducers
Redux 공식문서에 따라, 상태를 여러가지 관리하고 있을 때 combinedReducers에게 모든 상태의 reducer를 value로 하고, 그들에게 각각 부여할 상태 이름을 key로 하여 객체를 만들어 전달인자로 전달하면 더욱 간편하게 상태를 사용할 수 있다. 다음과 같이 작성한다.
// store.js
// createSlice로 각각 savedTodosReducer와 todayTodosReducer를 만들었다고 했을 때,
const { configureStore, combineReducers } = require('@reduxjs/toolkit');
import savedTodosReducer from './savedTodosSlice';
import todayTodosReducer from './todayTodosSlice';
const reducer = combineReducers({ todayTodos: todayTodosReducer, savedTodos: savedTodosReducer });
const store = configureStore({ reducer });
export default store;
🔨 createReducer.ts:283 Uncaught Error: A case reducer on a non-draftable value must not return undefined
createSlice의 전달인자 initialState를 원시값으로 지정했을 때 나오는 에러이다. createReducer 또는 createSlice를 사용할 때 초기값을 배열 또는 객체로 지정해주어야 한다.
'개발 > JS, TS, React' 카테고리의 다른 글
React useSelector와 useState를 함께 사용할 때 (0) | 2023.05.23 |
---|---|
React CORS에러 클라이언트에서 해결하기, proxy 2개 설정하기 (0) | 2023.04.30 |
Redux vanillaJS에서 사용하기 (0) | 2023.04.25 |
Redux란 / Redux React에서 사용하기 (0) | 2023.04.24 |
React State와 Props / Side effect / 순수함수 / Hooks (0) | 2023.04.06 |
- Total
- Today
- Yesterday
- 신불당 술집
- 공릉 술집
- 롯데월드 키오스크
- 태릉 꼬치
- 태릉삼겹살
- 이수 맛집
- 회고
- 홍천 삼겹살
- 태릉맛집
- 공릉 맛집
- sitemap
- 공릉 밀크티
- solo project
- 티스토리검색
- 공릉 꼬치
- Til
- 맥 깃허브 데스크탑
- 춘천맛집
- 을지로맛집
- 구글서치콘솔
- 티스토리
- 공릉맛집
- 태릉 술집
- 롯데월드 보조배터리
- 공릉 카페
- 공릉 이자카야
- 태릉 이자카야
- 롯데월드 매직패스 프리미엄
- 깃허브 데스크탑 로그아웃
- 춘천닭갈비
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |