Redux는 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너입니다. -redux
리덕스를 사용하면 컴포넌트들의 상태 관련 로직들을 다른 파일들로 분리시켜서 더욱 효율적으로 관리 할 수 있으며 글로벌 상태 관리도 손쉽게 할 수 있습니다. 또한, props drilling을 방지 할 수 있습니다.
props drilling: state를 전달하는 하위 컴포넌트가 많아지고 깊어질수록 props를 추적하거나 유지보수하기가 어려워지는 현상
리덕스 튜토리얼에 있는 내용입니다.
프로젝트에 Redux Toolkit 및 React-Redux 패키지를 추가합니다.
npm install @reduxjs/toolkit react-redux
src/app/store.js 파일을 만듭니다. 그 후 configureStore를 Redux Toolkit에서 import합니다.
빈 리덕스 스토어를 만들고 export 합니다.
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {}
})
이렇게 하면 Redux 스토어가 생성됩니다.
Provider를 import 해오면 <App>을 감싸도록 배치합니다.
만든 Redux 스토어를 가져와서 <Provider >의 props로 전달합니다.
// src/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')
)
새 파일 src/features/counter/counterSlice.js를 만들고 Redux Toolkit에서 createSlice를 import합니다.
슬라이스를 생성하려면 슬라이스를 식별하기 위한 문자열 이름, 초기 상태 값 및 상태를 업데이트할 수 있는 방법을 정의하는 하나 이상의 리듀서 함수가 필요합니다.
// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
export const counterSlice = createSlice({
name: 'counter', // 슬라이스를 식별하기 위한 문자열 이름
initialState: { // 초기 상태 값
value: 0
},
reducers: { // 상태를 업데이트할 수 있는 방법을 정의하는 하나 이상의 리듀서 함수
increment: state => {
// Redux Toolkit은 리듀서에서 "변경" 로직을 작성할 수 있게 해줍니다.
// 그러나 Immer 라이브러리를 사용하여 상태(state)를 직접 변경하지 않습니다.
// 대신 Immer는 "draft state"의 변경 사항을 감지하고 이를 기반으로 새로운 불변 상태를 생성합니다.
state.value += 1
},
decrement: state => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
}
}
})
// 각 케이스의 리듀서 함수에 대해 액션 생성자가 생성됩니다.
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
counterSlice에서 리듀서 함수를 가져와서 스토어에 추가해야 합니다. 리듀서 매개변수 내부에 필드를 정의함으로써 해당 상태(state)에 대한 모든 업데이트를 처리하기 위해 이 슬라이스 리듀서 함수를 사용하도록 스토어에 알려줍니다.
// src/app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice' //counterSlice 리듀서 함수 추가
export default configureStore({
reducer: {
counter: counterReducer
}
})
이제 React-Redux 훅을 사용하여 React 컴포넌트가 Redux 스토어와 상호작용하도록 할 수 있습니다.
useSelector를 사용하여 스토어에서 데이터를 읽을 수 있으며, useDispatch를 사용하여 액션을 디스패치(상태 변경)할 수 있습니다. <Counter> 컴포넌트를 가진 src/features/counter/Counter.js 파일을 만듭니다.
// src/features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice' // dispatch에서 사용할 상태 변경 함수
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>
)
}
버튼을 클릭할 때 마다 해당 Redux 작업이 스토어로 발송됩니다.
counterSlice 는 액션을 보고 상태를 업데이트 합니다.
<Counter>컴포넌트는 저장소에서 새 상태 값을 확인하고 새 데이터로 다시 렌더링합니다.
Redux 시작하기 -redux
Redux Toolkit Quick Start -redux
벨로퍼트와 함께하는 모던 리액트 06.redux
리액트 리덕스, React-Redux -rayong