Redux Toolkit Examples
What is Redux Toolkit?
Redux Toolkit is a package that includes utilities to simplify common Redux tasks like store setup, creating reducers, and writing immutable update logic. It also includes a powerful createSlice function that combines actions and reducers in a single place.
Key Features of Redux Toolkit:
- Simplified Store Setup:
configureStoreautomatically sets up the Redux store with good defaults. createSlice: Combines actions and reducers, reducing boilerplate.- Immutable Updates: Provides utilities that help write immutable update logic with less code.
- Built-in Middleware: Automatically includes
redux-thunkand other middleware for common use cases.
Basic Setup with Redux Toolkit
1. Install Redux Toolkit
First, install Redux Toolkit and React-Redux:
npm install @reduxjs/toolkit react-redux2. Create a Slice
A "slice" in Redux Toolkit is a collection of Redux reducer logic and actions for a single feature of your application. Here's an example of a counter slice:
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 },
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;3. Configure the Store
Use configureStore to set up the Redux store. This function automatically includes middleware like redux-thunk and sets up the Redux DevTools.
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
const store = configureStore({
reducer: {
counter: counterReducer,
},
});
export default store;4. Use Redux in a React Component
Now, you can use the Redux state and dispatch actions in your React components using the useSelector and useDispatch hooks from react-redux.
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './counterSlice';
const Counter = () => {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<h1>{count}</h1>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
<button onClick={() => dispatch(incrementByAmount(5))}>Increment by 5</button>
</div>
);
};
export default Counter;5. Integrate the Store with React
Wrap your application with the Provider component and pass in the Redux store.
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);Advanced Example: Async Thunks
Redux Toolkit makes it easy to handle asynchronous logic by using "thunks." Here's an example of how to fetch data asynchronously with createAsyncThunk.
1. Create an Async Thunk
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
// Async thunk to fetch user data
export const fetchUser = createAsyncThunk('user/fetchUser', async (userId) => {
const response = await fetch(`/api/user/${userId}`);
return response.json();
});
const userSlice = createSlice({
name: 'user',
initialState: { entity: {}, loading: 'idle' },
reducers: {},
extraReducers: (builder) => {
builder
.addCase(fetchUser.pending, (state) => {
state.loading = 'loading';
})
.addCase(fetchUser.fulfilled, (state, action) => {
state.entity = action.payload;
state.loading = 'idle';
})
.addCase(fetchUser.rejected, (state) => {
state.loading = 'failed';
});
},
});
export default userSlice.reducer;2. Dispatch the Thunk in a Component
import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchUser } from './userSlice';
const UserProfile = ({ userId }) => {
const dispatch = useDispatch();
const user = useSelector((state) => state.user.entity);
const loading = useSelector((state) => state.user.loading);
useEffect(() => {
dispatch(fetchUser(userId));
}, [dispatch, userId]);
if (loading === 'loading') return <div>Loading...</div>;
if (loading === 'failed') return <div>Error loading user data</div>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
};
export default UserProfile;Additional Resources
- Redux Toolkit Documentation (opens in a new tab)
- Redux Essentials Tutorial (opens in a new tab)
- Redux Toolkit Examples (opens in a new tab)
By using Redux Toolkit, you can streamline your Redux development process, reduce boilerplate code, and create a more maintainable and scalable state management solution for your React applications.