React
[React] redux-toolkit 사용 이유, redux와 비교
fnow
2024. 2. 5. 10:46
반응형
Redux toolkit은 Redux를 효율적으로 사용하기 위한 공식 라이브러리다. Redux를 사용하던 개발자들이 보다 쉽게 코드를 작성하고 유지보수할 수 있도록 해준다. Redux toolkit을 통해 Redux의 코드 복잡성을 줄이고, 보일러플레이트 코드(반복적인 코드)를 최소화하며, 개발자 경험을 향상할 수 있다.
왜 Redux Toolkit을 사용해야 하는가?
1. 간결한 코드
createSlice
와 configureStore
와 같은 간편한 함수들을 제공하여 보일러플레이트 코드를 최소화한다.
2. 불변성 유지
createSlice
는 내부적으로 Immer 라이브러리를 사용한다. Immer 라이브러리는 기존 객체를 직접적으로 수정해도 불변성을 유지될 수 있도록 해준다. Immer는 이전 상태를 변경하지 않고 새로운 상태를 생성한다.
기존 방식: 불변성 유지를 위해 새로운 객체 생성
function reducer(state = initialState, action) {
switch(action.type) {
case ADD:
return {
...state, // 기존 상태 객체를 전개하여 새로운 객체 생성
value: state.value + 1 // value 속성만 변경
}
case SUBTRACT:
return {
...state,
value: state.value - 1
}
default:
return state;
}
}
Immer를 사용한 방식: 불변성 유지를 간단하게 처리
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
add: state => {
state.value += 1; // 상태를 직접 변경하여도 새로운 객체가 생성됨
},
subtract: (state, action) => {
state.value -= action.payload;
}
}
})
3. 통합된 비동기 처리
createAsyncThunk
를 사용하여 비동기 작업을 쉽게 처리할 수 있다.
4. Redux DevTools 사용
Redux Toolkit도 Redux와 마찬가지로 Redux DevTools를 통해 디버깅할 수 있다.
Redux Toolkit 주요 기능과 장점
- createSlice 함수: 리듀서와 액션을 통합적으로 정의할 수 있는
createSlice
함수를 제공한다. - configureStore 함수: 스토어를 구성하는 데 사용되며, 여러 개의 리듀서를 효과적으로 결합하여 사용할 수 있다.
- Immer 라이브러리: 불변성 유지를 보다 쉽게 할 수 있다.
redux와 redux-toolkit 비교
redux 사용
// App.js
import { Provider, useSelector, useDispatch } from 'react-redux';
import { createStore } from 'redux';
// action type
const ADD = 'ADD';
const SUBTRACT = 'SUBTRACT';
// reducer
const initialState = {
value: 0
}
function reducer(state = initialState, action) {
switch(action.type) {
case ADD:
return {
...state,
value: state.value + 1
}
case SUBTRACT:
return {
...state,
value: state.value - 1
}
default:
return state;
}
}
// store
const store = createStore(reducer);
// counter component
function Counter() {
const dispatch = useDispatch();
const count = useSelector(state => state.value);
return (
<div>
<div>{count}</div>
<button onClick={() => dispatch( { type: ADD })}>+</button>
<button onClick={() => dispatch( { type: SUBTRACT })}>-</button>
</div>
)
}
function App() {
return (
<Provider store={store}>
<div className="App">
<Counter/>
</div>
</Provider>
);
}
export default App;
redux-toolkit으로 개선
// App.js
import { Provider, useSelector, useDispatch } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';
// reducer와 action이 통합된 작은 store
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
add: state => {
state.value += 1;
},
subtract: (state, action) => {
state.value -= action.payload;
}
}
})
// store 통합
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
}
})
// counter component
function Counter() {
const dispatch = useDispatch();
const count = useSelector(state => state.counter.value);
return (
<div>
<div>{count}</div>
{/* 방식1 */}
<button onClick={() => dispatch({ type: 'counter/add', payload: 3 })}>+</button>
{/* 방식2 */}
<button onClick={() => dispatch(counterSlice.actions.subtract(2))}>-</button>
</div>
)
}
function App() {
return (
<Provider store={store}>
<div className="App">
<Counter/>
</div>
</Provider>
);
}
export default App;
반응형