Optimizing Performance with Redux’s useSelector Shallow Equality
Present a scenario where the migration to Redux Toolkit 2.0 and the appropriate use of useSelector shallow equality can lead to performance improvements in React components.
import { useSelector, shallowEqual } from 'react-redux';
function MyComponent() {
// Using useSelector with shallowEqual to prevent unnecessary re-renders
const userData = useSelector(state => state.user.data, shallowEqual);
// Component logic...
return (
<div>
<h1>User Details</h1>
{/* Render user data */}
<p>Name: {userData.name}</p>
<p>Email: {userData.email}</p>
</div>
);
}
This code demonstrates how to utilize the 'shallowEqual' function from Redux with the 'useSelector' hook to fetch a slice of the state and prevent unnecessary re-renders. The useSelector hook accepts a selector function that extracts the necessary data (in this case 'state.user.data') and a comparison function (shallowEqual) which does a shallow equality check instead of a strict === check, avoiding re-renders when the selected state has not changed in a way that would affect the output of the selector.
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice';
// Configure the store with Redux Toolkit
const store = configureStore({
reducer: {
user: userReducer
}
});
export default store;
This piece of code sets up a Redux store using the Redux Toolkit configureStore function. When migrating to Redux Toolkit 2.0, this setup ensures that the store is configured correctly and ready to manage the state efficiently using the latest enhancements provided by Redux Toolkit.
import { createSlice } from '@reduxjs/toolkit';
// Example userSlice.js
export const userSlice = createSlice({
name: 'user',
initialState: {
data: {},
loading: false
},
reducers: {
setUserData: (state, action) => {
state.data = action.payload;
}
// other reducers...
}
});
export const { setUserData } = userSlice.actions;
export default userSlice.reducer;
In this code snippet, we create a user slice using createSlice function from the Redux Toolkit. The slice contains an initial state, some reducers, and corresponding actions. Using createSlice simplifies the creation of action types, action creators, and reducers in a single function call, making our codebase more maintainable and reducing boilerplate.
<!DOCTYPE html>
<html>
<head>
<title>Redux Shallow Equality Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.2/react-redux.min.js"></script>
<script src="./store.js"></script>
<script src="./userSlice.js"></script>
<script src="./MyComponent.js"></script>
</head>
<body>
<div id="root"></div>
<script>
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<MyComponent />
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
</script>
</body>
</html>
This HTML template includes the necessary script tags to load React, ReactDOM, Redux, and React-Redux libraries from the CDN. It also includes script tags for the store, userSlice, and MyComponent module files that should be created based on previous JavaScript code snippets. The root element is targeted to render the MyComponent wrapped with the Redux Provider, linking it to the Redux store to make the state accessible.