Before
// store/index.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.amount,
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;
// component/Counter.js
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", amount: 10 }); // { type: "increase", amount: 10 }
};
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 by 10</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
After
// store/index.js
import { createSlice, configureStore } from "@reduxjs/toolkit";
const initialState = { counter: 0, showCounter: true };
const counterSlice = createSlice({
name: "counter",
initialState,
reducers: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
},
increase(state, action) {
state.counter = state.counter + action.payload; // ** amount -> payload
},
toggleCounter(state) {
state.showCounter = !state.showCounter;
},
},
});
const store = configureStore({
reducer: counterSlice.reducer,
});
export const counterActions = counterSlice.actions;
export default store;
// component/Counter.js
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(10)); // { type: SOME_UNIQUE_IDENTIFIER, payload: 10 }
};
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 by 10</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
Multiple Slices
// store/index.js
import { createSlice, configureStore } from "@reduxjs/toolkit";
const initialCounterState = { counter: 0, showCounter: true };
const counterSlice = createSlice({
name: "counter",
initialState: initialCounterState,
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 initialAuthState = {
isAuthenticated: false,
};
const authSlice = createSlice({
name: "authentication",
initialState: initialAuthState,
reducers: {
login(state) {
state.isAuthenticated = true;
},
logout(state) {
state.isAuthenticated = false;
},
},
});
const store = configureStore({
reducer: { counter: counterSlice.reducer, auth: authSlice.reducer }, // <---- 1. reducer changed
});
export const counterActions = counterSlice.actions;
export const authActions = authSlice.actions;
export default store;
// component/Counter.js
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.counter); // <---- 1. should be changed because reducer changed
const show = useSelector((state) => state.counter.showCounter); // <---- 1. should be changed because reducer changed
const incrementHandler = () => {
dispatch(counterActions.increment());
};
const increaseHandler = () => {
dispatch(counterActions.increase(10)); // { type: SOME_UNIQUE_IDENTIFIER, payload: 10 }
};
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 by 10</button>
<button onClick={decrementHandler}>Decrement</button>
</div>
<button onClick={toggleCounterHandler}>Toggle Counter</button>
</main>
);
};
export default Counter;
Split
Split files
// store/index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counter";
import authReducer from "./auth";
const store = configureStore({
reducer: { counter: counterReducer, auth: authReducer },
});
export default store;
// store/auth.js
import { createSlice } from "@reduxjs/toolkit";
const initialAuthState = {
isAuthenticated: false,
};
const authSlice = createSlice({
name: "authentication",
initialState: initialAuthState,
reducers: {
login(state) {
state.isAuthenticated = true;
},
logout(state) {
state.isAuthenticated = false;
},
},
});
export const authActions = authSlice.actions;
export default authSlice.reducer;
// store/counter.js
import { createSlice } from "@reduxjs/toolkit";
const initialCounterState = { counter: 0, showCounter: true };
const counterSlice = createSlice({
name: "counter",
initialState: initialCounterState,
reducers: {
increment(state) {
state.counter++;
},
decrement(state) {
state.counter--;
},
increase(state, action) {
state.counter = state.counter + action.payload;
},
toggleCounter(state) {
state.showCounter = !state.showCounter;
},
},
});
export const counterActions = counterSlice.actions;
export default counterSlice.reducer;
And then, update all import statement
import { authActions } from "../store/auth";
import { counterActions } from "../store/counter";