There is a pattern I was using on a project where most of the state resides on redux. I also try to keep the application logic close to redux, so I use selectors and I wrap all the possible actions to be taken into custom hooks.
Running some profiling tests I noticed that, when I use my custom hooks (example below) all the components that use them re-render when the redux state changes:
export const useDefinitionForm = () => {
const { description, step } = useAppSelector((state) => {
const { name, color, icon, duration } = state.descriptionForm;
return { description: { name, color, icon, duration }, step: state.descriptionForm.step };
});
const dispatch = useAppDispatch();
return { description, step, actions: bindActionCreators(actions, dispatch) };
};
However, when I use the useDispatch and useSelector hooks directly on the target component, then those components only re-render when the specific redux section changes:
const DurationSection = () => {
const dispatch = useAppDispatch();
const duration = useAppSelector((state) => state.descriptionForm.duration);
return (
<Section title="Expected duration" hint={duration} step="duration">
<Typography variant="subtitle1">How much will this task usually last?</Typography>
<DurationSlider
value={duration}
onChange={(value) => dispatch(setDuration(value))}
valueLabelDisplay="on"
/>
</Section>
);
};
Why is this? How can I change the custom hooks so they are as performant as using the hooks directly on the component? I try to keep the components as dumb as possible.