Implementing the Entity Adapter for Normalizing State
Walk through the process of migrating a manually managed normalized state to using the createEntityAdapter API from Redux Toolkit 2.0, focusing on CRUD operations.
import { createSlice, createEntityAdapter } from '@reduxjs/toolkit';
// Define a type for the slice state
interface UserState {
ids: string[];
entities: Record<string, UserType>;
}
// Create an entity adapter
const userAdapter = createEntityAdapter<UserType>();
// Define the initial state using the adapter's getInitialState method
const initialState = userAdapter.getInitialState();
// Define the slice
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
// Reducer handlers using the adapter's methods for easy CRUD operations
addUser: userAdapter.addOne,
addUsers: userAdapter.addMany,
updateUser: userAdapter.updateOne,
removeUser: userAdapter.removeOne
}
});
export const { addUser, addUsers, updateUser, removeUser } = userSlice.actions;
export default userSlice.reducer;
This code sets up a Redux slice using createEntityAdapter from Redux Toolkit 2.0 to normalize and manage the state for user entities. It defines a type for the slice state, creates an entity adapter with initial state, defines the slice with CRUD operation reducers using adapter methods, and exports the actions and reducer.
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice';
// Configure the store with the userReducer
const store = configureStore({
reducer: {
user: userReducer
}
});
export default store;
This code creates the Redux store and configures it with the user reducer created from the previous userSlice.
import { useSelector, useDispatch } from 'react-redux';
import { addUser, updateUser, removeUser } from './userSlice';
// Dispatch actions with the useDispatch hook
const dispatch = useDispatch();
dispatch(addUser({ id: '1', name: 'John Doe' }));
dispatch(updateUser({ id: '1', changes: { name: 'Jane Doe' } }));
dispatch(removeUser('1'));
// Access normalized state with the useSelector hook
const users = useSelector(state => state.user.entities);
This code demonstrates how to dispatch actions and access the normalized state in a React component using the hooks from react-redux.
<!-- HTML -->
<div id='app'></div>
This is the HTML markup with a root div where the React application will be mounted.
/* CSS */
#app {
margin: 20px;
font-family: Arial, sans-serif;
}
This is the CSS style for the root div of the app.