Manage complex global state with a single source of truth. Data flows in one direction: Action → Reducer → Store.
With Redux Toolkit (RTK), we define "Slices". A slice contains the reducer logic and actions for a specific feature.
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: state => {
// Immer lets us "mutate" logic in reducers!
state.value += 1;
},
decrement: state => {
state.value -= 1;
}
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;Combine all your slices into the central store.
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
// user: userReducer,
// cart: cartReducer...
},
});Use `useSelector` to read from the store, and `useDispatch` to send actions.
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
function Counter() {
const count = useSelector(state => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(decrement())}>-</button>
</div>
);
}Don't use Redux for everything! Use it when:
React's built-in hooks can do a lot, but Redux offers more structure for complex apps.
| Feature | Redux Toolkit | Context + useReducer |
|---|---|---|
| State Location | Single External Store | React Component Tree |
| Performance | Optimized (Selectors) | Requires Manual Optimization |
| DevTools | Excellent (Time Travel) | Basic (React DevTools) |
| Middleware | Built-in (Thunk, Saga) | Manual Implementation |