Redux toolkit은 Redux logic 작성의 표준이 되기 위해 탄생했습니다. 리덕스 툴킷은 아래와 같은 리덕스의 3가지 문제점을 해결해줍니다.
Redux toolkit은 create-react-app처럼 세팅 과정과 보편적 use cases에 대한 추상화를 제공하는 기능을 지원합니다. 또한 사용자가 어플리케이션 코드를 간편화하기 위한 유용한 툴도 제공합니다.
또한 RTK Query라고 하는 분리된 데이터 패칭 툴을 제공합니다. 이와 관련된 내용은 다음 포스팅에서 다뤄보겠습니다.
Redux toolkit은 모든 리덕스 사용자들에게 더 나은 코드베이스를 제공하기 위해 탄생한 도구입니다.
일반적으로 가장 추천되는 방법입니다.
# Redux + Plain JS template
npx create-react-app my-app --template redux
# Redux + TypeScript template
npx create-react-app my-app --template redux-typescript
#NPM
npm install @reduxjs/toolkit
#Yarn
yarn add @reduxjs/toolkit
window.RTK 글로벌 변수를 제공하는 UMD 패키지로도 사용이 가능합니다. UMD 패키지는 script태그를 이용해 바로 이용할 수 있습니다.
Redux toolkit은 다음과 같은 API를 포함하고 있습니다.
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
위 코드는 Redux store를 생성하고, 자동으로 Redux DevTools extension을 설정해줍니다.
스토어가 생성되면 React-Redux의 Provider 세팅을 통해 React components에서 사용 가능하도록 설정할 수 있습니다.
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
slice생성은 string name, initial state value, state 업데이트에 대한 one or more reducer functions가 필요합니다. Redux toolkit의 createSlice와 createReducer API는 내부적으로 Immer를 사용하여 일반적 'mutating' update logic이 correct immutable updates가 되도록 도와줍니다.
// features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
},
}
})
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
이제 reducer 함수를 counter slice로 부터 import하여 우리의 store에 추가해야 합니다. reducer parameter안의 field를 정의함으로써 상태 변화시 store에 slice reducer function을 사용하도록 할 수 있습니다.
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export const store = configureStore({
reducer: {
counter: counterReducer,
},
})
이제 React-Redux hooks를 통해 리액트 컴포넌트에서 redux store와 상호작용 하도록 사용할 수 있습니다. store로 부터 data를 읽기 위해 useSelector를, action dispatch를 위해 useDispatch를 사용할 수 있습니다. Counter 컴포넌트를 만들고 이를 App에서 렌더링 하도록 개발합니다.
// features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}
이제 Increment, Decrement 버튼을 클릭하면 다음과 같은 일이 일어납니다.
리덕스 툴킷은 리덕스를 Wrapping하여 쉽게 사용할 수 있도록 도와주는 도구입니다. 따라서 Redux Essentials와 Redux Fundamentals tutorial을 읽어본다면 Redux가 어떻게 동작하는지, Redux toolkit이 어떤 역할을 해주는지, 어떻게 완벽하게 사용할 수 있는지 알 수 있을 것입니다.
출처