리덕스의 상태 데이터가 많아질수록 객체 내부의 데이터의 양이 방대해진다. 그럴 때마다 액션 로직 또한 해당 객체의 양식을 그대로 리턴해야 되기 때문에 리덕스 코드가 길어지고, 파일이 무거워질 수밖에 없다. 이런 경우 어떻게 할까? 실수로 중첩된 데이터 등을 바꿀 수 없도록 할 수는 없을까?
npm install @reduxjs/toolkit
import { createSlice, configureStore } from '@reduxjs/toolkit';
const initialState = { counter: 0, showCounter: true };
/*
! 모든 slice는 name이 있어야 한다.
=> 상태마다 식별자가 필요하다는 것
payload가 있는 경우에는 어떻게 할까? 기본적으로 payload를 dispatch를 통해서
전달하게 되면 payload가 default 키값으로 들어가기 때문에 action.payload로 접근해야 한다.
*/
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increase(state) {
state.counter = state.counter + 1;
},
increaseByInput(state, action) {
state.counter = state.counter + action.payload;
},
decrease(state) {
state.counter = state.counter - 1;
},
toggle(state) {
state.showCounter = !state.showCounter;
},
},
});
// configureStore가 여러개의 리듀서들을 통합해 주는 역할을 하는 것 같다.
const store = configureStore({
reducer: counterSlice.reducer,
});
//! 액션 생성자
export const counterActions = counterSlice.actions;
export default store;
import classes from './Counter.module.css';
import { useSelector, useDispatch } from 'react-redux';
import { counterActions } from '../store/index';
const Counter = () => {
const dispatch = useDispatch();
const counter = useSelector((state) => state.counter);
const showCounter = useSelector((state) => state.showCounter);
/*
! 툴킷 사용시 액션 생성자를 불러와 사용하려는 reducers를 실행한다.
? 페이로드가 있는 경우에는 매개변수로 페이로드 값을 담아 보내주자!
*/
const incrementHandler = () => {
dispatch(counterActions.increase());
};
//! increaseHandler에 페이로드 연결하기
const increaseHandler = () => {
dispatch(counterActions.increaseByInput(5));
};
const decrementHandler = () => {
dispatch(counterActions.decrease());
};
const toggleCounterHandler = () => {
dispatch(counterActions.toggle());
};
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
{showCounter && <div className={classes.value}>{counter}</div>}
<div>
<button onClick={incrementHandler}>INCREASE BUTTON</button>
<button onClick={increaseHandler}>INCREASE by 5</button>
<button onClick={decrementHandler}>DECREASE BUTTON</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;