We currently have a redux state with nested models with the following structure.
{
groups: {
ids: [],
status: {},
error: {}
},
members: {
ids: [],
status: {},
error: {}
}
For convenience, each model has an exported hook, typed as;
export const useGroupState = () => useTypedState((state) => state.groups);
And used like so;
const { ids } = useGroupState()
We use this syntax throughout our app. However we recently noticed that upon any state change to the GroupState, even if it does not modify ids, causes a rerender. If Groups.status updates, anything destructing with the above syntax will rerender.
We solved this by using
const ids = useTypedState(({groups}) => groups.ids)
However, the old syntax is convenient and is fairly widespread. Is there a way we could retain the old syntax but fix the re-render behavior?
Thanks,
I don't know the exact implementation of the useTypedState
hook here, but assuming it uses the React-Redux useSelector
hook inside: yes, this is entirely expected behavior. useSelector
re-renders if the returned reference has changed since last time. If you return an object, and that object gets immutably updated, then it's a new reference and will force a re-render. Destructuring only some of the fields happens after the render is in progress.
Your component should always select the smallest amount of actual state that it needs.