store/index.js
- toolkit 을 사용하지 않았을 때 코드
- 리액트 앱과 리덕스 스토어를 연결한다.
- 앱의 컴포넌트가 디스패치하고 들을 수 있다.
- 전체 순서
store/index.js > index.js > components/counter.js
import { createStore } from "redux";
const initialState = { counter: 0, showCounter: true };
const counterReducer = (state = initialState, action) => {
if (action.type === "increment") {
return {
counter: state.counter + 1,
showCounter: state.showCounter,
};
}
if (action.type === "increase") {
return {
counter: state.counter + action.payload,
showCounter: state.showCounter,
};
}
if (action.type === "decrement") {
return {
counter: state.counter - 1,
showCounter: state.showCounter,
};
}
if (action.type === "toggle") {
return {
showCounter: !state.showCounter,
counter: state.counter,
};
}
return state;
};
const store = createStore(counterReducer);
export default store;
- toolkit 을 사용했을 때 코드
- name, 기본값, reducers를 객체로 정의한다.
- 위의 코드와는 다르게 툴킷을 이용하면 기존의 값을 변경해주는 것을 방지해줘서
state.counter++
같은 코드를 사용해도 괜찮다.
import { createSlice, configureStore } from "@reduxjs/toolkit";
const initialState = { counter: 0, showCounter: true };
const counterSlice = createSlice({
name: "counter",
initialState: initialState,
reducers: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
},
increase(state, action) {
state.counter = state.counter + action.payload;
},
toggleCounter(state) {
state.showCounter = !state.showCounter;
},
},
});
const store = configureStore({
reducer: counterSlice.reducer,
});
export const counterActions = counterSlice.actions;
export default store;
components/Counter.js
- toolkit 을 사용하지 않았을 때 코드
- useSelector을 사용하는 이유는 자동으로 구독을 해준다. 따라서 리덕스 저장소에서 데이터가 변경될 때마다 자동으로 업데이트 되고 최신 상태를 유지
- useSelector을 사용해서 저장소가 관리하는 데이터에 액세스(이용) 할 수 있다.
- useSelector가 받는 콜백 함수는 react-redux가 실행해준다.
- useDispatch는 스토어에 대한 액션을 보낸다.
import { useSelector, useDispatch } from "react-redux";
import classes from "./Counter.module.css";
const Counter = () => {
const dispatch = useDispatch();
const counter = useSelector((state) => state.counter);
const show = useSelector((state) => state.showCounter);
const incrementHandler = () => {
dispatch({ type: "increment" });
};
const increaseHandler = () => {
dispatch({ type: "increase", payload: 2 });
};
const decrementHandler = () => {
dispatch({ type: "decrement" });
};
const toggleCounterHandler = () => {
dispatch({ type: "toggle" });
};
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
{show && <div className={classes.value}>{counter}</div>}
<div>
<button onClick={incrementHandler}>Increment</button>
<button onClick={increaseHandler}>increase</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
- toolkit 을 사용했을 때 코드
- 툴킷이 자동으로 해주는 것이 많아서 코드를 간단히 할 수 있다.
import { useSelector, useDispatch } from "react-redux";
import { counterActions } from "../store/index";
import classes from "./Counter.module.css";
const Counter = () => {
const dispatch = useDispatch();
const counter = useSelector((state) => state.counter);
const show = useSelector((state) => state.showCounter);
const incrementHandler = () => {
dispatch(counterActions.increment());
};
const increaseHandler = () => {
dispatch(counterActions.increase(2));
};
const decrementHandler = () => {
dispatch(counterActions.decrement());
};
const toggleCounterHandler = () => {
dispatch(counterActions.toggleCounter());
};
return (
<main className={classes.counter}>
<h1>Redux Counter</h1>
{show && <div className={classes.value}>{counter}</div>}
<div>
<button onClick={incrementHandler}>Increment</button>
<button onClick={increaseHandler}>increase</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;