In a React/Hooks/ReduxToolkit application, what are the efficiency implications of selecting a slice of the redux store in the following two methods:
Store Structure:
const store: RootState = { students, courses, }
students
is a dictionary of students indexed by their id
... i.e.
students: [id: number]: Student
Similarly, courses
is a dictionary of courses indexed by their id
In a component that is only concerned with rendering student
information, what are the performance implication of directly selecting for the relevant slice in the component versus creating a memoized selector that the component then invokes?
Case 1 (direct selecting of slice in component):
const StudentReactComponent = () => {
const allStudents = useSelector((state: RootState) => state.students)
...
return some render logic that makes use of `allStudents`
...
}
Case 2 (selecting a slice via a memoized selector):
// This memoized selector would actually be imported from a `studentSelectors`
// module instead of being declared above the react component
const selectStudentsDictionary = createSelector((state: RootState) => state.students, students => students)
const StudentReactComponent = () => {
const allStudents = useSelector(selectStudentsDictionary)
...
return some render logic that makes use of `allStudents`
...
useSelector
forces a component to re-render when the selector returns a new reference that is different than the previous reference: https://react-redux.js.org/api/hooks#equality-comparisons-and-updates . So, as written, the component will re-render whenever state.students
changes.
The "memoized" selector in this example is actually useless. Memoization only matters when you have derived data. Any time you have a createSelector
instance that just has x => x
as its "output selector", you're using createSelector
the wrong way, and this could likely just be a plain function.
As a related side note, I am actually planning to write a new "Selectors and Memoization" usage guide page for the Redux core docs in the near future. Until then, I'd suggest reading through my post Using Reselect Selectors for Encapsulation and Performance. It's a few years old, but still mostly relevant here.