[리덕스] React - Redux의 전반적인 이해, 2022
기존에 프로젝트를 진행할 때 상태관리에 있어서 리덕스 구조를 사용해 왔습니다.
그런데 최근 리덕스 Tool-kit이 나오고 공식 홈페이지에서도 이를 적극 활용할 것을 추천하고 있습니다.
이번 글에서는 React-Redux 프로젝트의 생성 과 생성하면 기본적으로 세팅되는 Redux 구조와 State 관리에 대해서 알아보려고 합니다.
설치
리액트 + 리덕스 프로젝트 생성
프로젝트를 만들 폴더에서 VSCode에서 터미널을 열고, 다음과 같은 명령어를 입력합니다.
npx create-react-app [프로젝트 명] --template redux
기존 프로젝트 + 리덕스
만약 기존 프로젝트에 리덕스를 추가하고 싶다면 다음과 같은 명령어를 통해 리덕스를 추가할 수 있습니다.
redux, react-redux
npm i redux
npm i react-redux
리액트 프로젝트에 리덕스를 추가하고 싶다면 위의 2가지 모듈의 설치가 필요합니다.
Redux Toolkit
리덕스 설치가 끝났다면 리덕스 Toolkit도 설치해줍니다.
Redux Toolkit은 Redux 로직을 작성하기 위해 공식 문서에서 추천하는 방법입니다.
Redux Toolkit에는 리덕스 앱을 만들기에 필수적으로 여기는 패키지와 함수들을 포함합니다.
이는 더 나은 Redux 코드를 만들도록 도와줍니다.
다음과 같은 명령어를 통해 RTK(Redux Tool-Kit)를 설치해줍니다.
npm install @reduxjs/toolkit
RTK에는 immer, redux, redux-devtools-extension 가 자체 내장되어 있습니다.
React - Redux의 전반적인 상태관리 방법 (from, redux tool-kit)
configureStore
초기 store는 이러한 형태를 가집니다.
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {},
})
Provider
리액트 리덕스는 <Provider /> 컴포넌트를 통해 리덕스 store를 이용 가능하게 합니다.
<Provider> 컴포넌트는 <App />을 감싸는 형태입니다.
index.js
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')
)
Create a Redux State Slice - 리덕스 slice reducer 생성
createSlice() API 내부에는
다음과 같은 방식으로 state 이름, 초기값, reducer 함수(actions)을 정의합니다.
Reducer 함수들은 Immer를 사용하여 mutate한 성질을 갖습니다.
import { createSlice } from '@reduxjs/toolkit'
export const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
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
Add Slice Reducers to the Store - store 안에 slice reducer 추가
다음으로 store에 reducer를 import하고, reducers 안에 넣어줍니다.
configureStore는 reducer를 저장합니다.
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export default configureStore({
reducer: {
counter: counterReducer,
},
})
Use Redux State and Actions in React Components
(컴포넌트에서 state 사용 및 값 변경(action, dispatch))
컴포넌트에서 리액트 리덕스 hook을 사용합니다.
컴포넌트 상에서 store의 데이터(state)를 useSelector를 통해 읽을 수 있습니다.
action이 store로 dispatch(전송)됩니다.
Counter slice reducer는 해당 action을 하고, state 값을 변경합니다.
<Counter> 컴포넌트는 store로부터 변경된 state 값을 받습니다.
그리고 새로운 값이 전달되면 해당 컴포넌트는 re-rendering됩니다.
features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'
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>
)
}
본 게시글은 리덕스의 공식 홈페이지를 참고하여 작성하였습니다.
https://ko.redux.js.org/introduction/installation