티스토리 뷰
Redux 공식문서에서 Redux Toolkit 사용을 공식적으로 적극 추천한다. 기존 Redux에서 작업을 단순화하고, 흔한 실수를 방지하여 Redux 어플리케이션을 더 쉽게 만들 수 있도록 한다.
기존의 Redux를 React, vanillaJS에서 사용하는 방법은 각각 다음의 포스팅에서 확인할 수 있다.
Redux란 / Redux React에서 사용하기
Redux는 JavaScript 어플리케이션의 상태를 관리할 수 있는 상태 관리 라이브러리이다.(React, Vue, Angular, vanilla JS 등 모두 사용할 수 있다.) React로 상태 관리를 할 때 props drilling이나 상태끌어올리기를
hahagarden.tistory.com
Redux vanillaJS에서 사용하기
html파일에서 간단하게 증감버튼을 만들고, JavaScript파일로 DOM조작을 하고, Redux로 상태를 관리한다. add minus DOM조작을 위해 브라우저 환경에서 작업하였다. 리액트를 주로 사용했어서 자연스럽게
hahagarden.tistory.com
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
- 태릉맛집
- 춘천닭갈비
- 공릉 맛집
- 신불당 술집
- 구글서치콘솔
- 공릉 술집
- 을지로맛집
- 홍천 삼겹살
- 회고
- 티스토리
- 공릉 꼬치
- 태릉 꼬치
- 태릉삼겹살
- 공릉 카페
- 롯데월드 매직패스 프리미엄
- Til
- 공릉 이자카야
- sitemap
- 이수 맛집
- 롯데월드 보조배터리
- solo project
- 공릉맛집
- 티스토리검색
- 맥 깃허브 데스크탑
- 춘천맛집
- 롯데월드 키오스크
- 태릉 이자카야
- 깃허브 데스크탑 로그아웃
- 공릉 밀크티
- 태릉 술집
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |