리덕스 툴킷을 쓰면 리덕스를 조금 더 쉽게 이용이 가능할까요?
한번 만들어 봅시다. ( 후기 : 미쳤음 너무 좋음)
npm install @reduxjs/toolkit react-redux
configureStore
를 툴킷에서 가져옵니다. → 기존의 createStore를 대체합니다.
빈 redux 저장소를 만들고 내보내는 것으로 시작하겠습니다.
// app/store.js
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
를 이용해서 방금 만든 저장소(store)를 Provider를 통해 전체 컴포넌트를 가진 App.js
를 둘러싸이게 합니다.
import { store } from './app/store'
import { Provider } from 'react-redux'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
리덕스 로직을 작성할 떄는 createSlice
를 이용합니다. ⇒ action,reducer를 대신합니다
Toolkit 에서 createSlice 라는 함수를 들고옵니다.
슬라이스가 생성되면 Redux 액션 생성자와 전체 슬라이스에 대한 리듀서 기능을 내보낼 수 있습니다.
// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
},
})
// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
카운터 슬라이스에서 리듀서 함수를 가져와서 스토어에 추가해야 합니다.
변수 내부에 필드를 정의함으로써 reducer 스토어에 이 슬라이스 감소기 기능을 사용하여 해당 상태에 대한 모든 업데이트를 처리하도록 지시합니다.
?? counterReducer는 어디서 받아온거지?
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export default configureStore({
reducer: {
counter: counterReducer,
},
})
이제 React-Redux 에서 사용가능합니다.
useSelector를 이용해 데이터를 읽을 수 있으며
useDispatch를 사용해 작업을 전달 할 수 있습니다.
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>
)
}
import {useState} from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment,incrementbyAmount } from './counterSlice'
export function Counter() {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
const [value,setValue] = useState("")
const increaseNums = ()=>{
dispatch(incrementbyAmount(value))
setValue("")
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>
<input value={value} onChange={(e)=>setValue(e.target.value)}/>
<button onclick={()=>{increaseNums()}}>{value} 만큼 올리기</button>
</div>
</div>
)
}
// src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
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
// src/app/rootReducer
const rootReducer = combineReducer ({
user : userSlice.reducer,
posts : postSlice.reducer
})
module.exports = rootReducer?