Redux
1. 시작
- 설치
npm install redux react-redux
- store 생성
import {createStore} from 'redux'
function reducer(state, action) {
// ...
return newState
}
const store = createStore(reducer);
export default store
2. Provider
import {Provider} from 'react-redux'
import store from './store'
function App() {
return (
<div className="App">
<h1>Root</h1>
<div className="Grid">
<Provider store={store}>
<Left1></Left1>
<Right1></Right1>
</Provider>
</div>
</div>
);
}
export default App;
3. Hooks
- useSelector(Left3.jsx)
import { useSelector } from "react-redux"
export default function Left3() {
const number = useSelector((state) => state.number);
return (
<div>
<h3>Left3 : {number}</h3>
</div>
)
}
- useDispatch(Right3.jsx)
import { useDispatch } from "react-redux"
export default function Right3() {
const dispatch = useDispatch();
return (
<div>
<h3>Right3</h3>
<button onClick={() => {dispatch({type:'PLUS'})}}>+</button>
</div>
)
}
4. Redux Toolkit
createStore 대신(from redux) 사용하게 될 createSlice 제공
조금 더 직관적인 코드 작성 가능
유지보수 간편
Install
$ npm install @reduxjs/toolkit react-redux
Create a Redux Store & Add Slice Reducers to the Store
- app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
// 작성한 slice를 store에 등록
export default configureStore({
reducer: {
counter: counterReducer,
},
})
Provide the Redux Store to React
- index.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import store from './app/store'
import { Provider } from 'react-redux'
// As of React 18
const root = ReactDOM.createRoot(document.getElementById('root'))
// 최상위 컴포넌트에 Provider
root.render(
<Provider store={store}>
<App />
</Provider>
)
Create a Redux State Slice
- features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
// 기본 상태 및 상태관리 reducer 등록
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
},
},
})
// dispatch를 위한 export
export const { increment, decrement, incrementByAmount } = counterSlice.actions
// The function below is called a thunk and allows us to perform async logic. It
// can be dispatched like a regular action: `dispatch(incrementAsync(10))`. This
// will call the thunk with the `dispatch` function as the first argument. Async
// code can then be executed and other actions can be dispatched
export const incrementAsync = (amount) => (dispatch) => {
setTimeout(() => {
dispatch(incrementByAmount(amount))
}, 1000)
}
// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: `useSelector((state) => state.counter.value)`
export const selectCount = (state) => state.counter.value
export default counterSlice.reducer
Use Redux State and Actions in React Components
- 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'
// useSelector를 이용하여 store에 등록된 counter slice에서 value 값을 가져옴
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>
)
}
정리
현재 리액트 최신버전에서는 createStore을 권장하지 않고 있습니다.
그래서 redux-toolkit에 익숙해져야겠습니다.
'개발일기 > Web' 카테고리의 다른 글
[React] 로그인 후 이전 페이지로 이동 구현 (0) | 2022.10.11 |
---|---|
[React] 파일 업로드 및 미리보기 구현 + input태그 버튼연결하기 (0) | 2022.10.11 |
[Node.js] socket.io를 활용하여 채팅구현하기 (2) | 2022.06.16 |
[Django] Django 기초(프로젝트 및 앱 만들기) (0) | 2022.03.03 |
[Python] 가상환경(virtual environment) 사용하기 (0) | 2022.03.03 |