명령어: yarn add react-redux @reduxjs/toolkit
코드비교
<일반 리덕스 예시 코드>
- Action value
const ADD_NUMBER = "ADD_NUMBER";
const MINUS_NUMBER = "MINUS_NUMBER";
- Action creator
export const addNumber = (payload) =>{
return {
type: ADD_NUMBER,
payload,
};
};
export const minusNumber = (payload) =>{
return {
type:MINUS_NUMBER,
payload,
};
};
- InitialState 초기값
const initialState = {
number: 0,
}
- reducer
const counter = (state = initialState,action) => {
switch (action.payload) {
case ADD_NUMBER:
return {
number: state.number + action.payload,
};
case MINUS_NUMBER:
return {
number:state.number - action.payload,
};
default:
return state;
};
};
export default counter;
import {createSlice} from "@reduxjs/toolkit";
const initialState = {
number: 0,
};
const counterSlice = createSlice({
name: "counter", // 모듈의 이름 -> 전: Action value
initialState, // 이 모듈의 초기상태 값
reducers: { // 이 모듈의 Reducer 로직
// 리듀서 안에서 만든 함수가 리듀서 로직이자 액션 크리에이터
addNumber: (state,action) => {
state.number = state.number + action.payload;
},
minusNumber: (state,action) =>{
state.number = state.number - action.payload;
},
},
});
// 액션크리에이터는 컴포넌트에서 사용하기 위해 export 함
export const {addNumber, minumNumber} = counterSlice.actions;
export default counterSlice.reducer;
import { configureStore } from "@reduxjs/toolkit";
/**
* slice.reducer import
*/
import counter from "../modules/counterSlice";
import todos from "../modules/todosSlice";
/**
* 모듈(Slice)이 여러개인 경우
* 추가할때마다 reducer 안에 각 모듈의 slice.reducer를 추가해줘야 합니다.
*
* 아래 예시는 하나의 프로젝트 안에서 counter 기능과 todos 기능이 모두 있고,
* 이것을 각각 모듈로 구현한 다음에 아래 코드로 2개의 모듈을 스토어에 연결해준 것 입니다.
*/
const store = configureStore({
reducer: { counter: counter, todos: todos },
});
export default store;
dispatch(함수) → 함수실행 → 함수안에서 dispatch(객체)
// src/ redux//modules/counterSlice
import {createSlice, createAsyncThunk} from "@reduxjs/toolkit";
export const __addNumber = createAsyncThunk(
// 첫번째인자 action value
"addNumber",
// 두번째 인자 : 콜백함수
(payload,thunkAPI) =>{
setTimeout(()=>{
thunkAPI.dispatch(addNumber(payload))
},3000);
}
);
const initialState = {
number: 0,
};
const counterSlice = createSlice({
name: "counter",
initialState,
reducers : {
addNumber: (state, action) => {
state.number = state.number + action.payload;
},
minusNumber: (state,action) => {
state.number = state.number - action.payload;
},
},
});
export const {addNumber, minusNumber} = counterSlice.actions;
export default counterSlice.reducer;
import {useDispatch,useSelector} from 'react-redux';
import {useState} from 'react';
import { __addNumber,minusNumber } from './redux/modules/counter2Slice';
const App = () => {
const dispatch = useDispatch();
const [number, setNumber] = useState(0);
const GlobalNumber = useSelector((state)=>state.counter.number);
const onChangeHandler = (event) =>{
const {value} = event.target;
setNumber(+value);
};
const onClickaddNumberHandler = () =>{
dispatch(__addNumber(number));
};
const onClickminusNumberHandler = () =>{
dispatch(minusNumber(number));
};
// thunk함수를 디스패치한다. payload는 thunk 함수에 넣어주면
// 리덕스 모듈에서 payload로 받을 수 있다.
return (
<div>
<div>{GlobalNumber}</div>
<input type="number" onChange={ onChangeHandler}/>
<button onClick={onClickaddNumberHandler}>더하기</button>
<button onClick={ onClickminusNumberHandler}>빼기</button>
</div>
);
};
export default App;