Optimizing Reducer Performance with Reselect Selectors
Create a code snippet that combines Redux Toolkit’s createReducer with Reselect selectors to compute derived data from the nested state, demonstrating how to avoid unnecessary computations.
import { createReducer } from '@reduxjs/toolkit';
import { createSelector } from 'reselect';
// An initial state for our reducer
const initialState = {
userData: {
firstName: 'John',
lastName: 'Doe',
details: { age: 30, location: 'New York' }
}
};
// A simple action for updating user details
const updateUserDetails = {
type: 'updateUserDetails',
payload: { age: 32, location: 'San Francisco' }
};
// Our reducer using createReducer from Redux Toolkit
const userReducer = createReducer(initialState, {
[updateUserDetails.type]: (state, action) => {
state.userData.details = action.payload;
}
});
// A selector for getting the user's full name
const selectFullName = createSelector(
state => state.userData,
userData => `${userData.firstName} ${userData.lastName}`
);
// A memoized selector for getting the user's details only when they change
const selectUserDetails = createSelector(
state => state.userData.details,
userDetails => userDetails
);
export { userReducer, selectFullName, selectUserDetails };
This code defines a userReducer using Redux Toolkit's createReducer, handling an action for updating user details. It uses Reselect's createSelector to create a memoized selector selectFullName to compute a user's full name and another memoized selectUserDetails for user details. These selectors only recompute when the relevant parts of the state change, preventing unnecessary recalculations.