Reputation: 39
Considering this state, I need to select some data from it:
const initialState: PlacesStateT = {
activeTicket: null,
routes: {
departure: {
carriageType: 'idle',
extras: {
wifi_price: 0,
linens_price: 0,
},
},
arrival: {
carriageType: 'idle',
extras: {
wifi_price: 0,
linens_price: 0,
},
},
},
};
so, I came up with two approaches:
first:
const useCoaches = (dir: string) => {
const name = mapDirToRoot(dir);
const carType = useAppSelector((state) => state.places.routes[name].carriageType);
const infoT = useAppSelector((state) => {
return state.places.activeTicket.trainsInfo.find((info) => {
return info.routeName === name;
});
});
const coaches = infoT.trainInfo.seatsTrainInfo.filter((coach) => {
return coach.coach.class_type === carType;
});
return coaches;
};
and second:
const handlerActiveCoaches = (name: string) => (state: RootState) => {
const { carriageType } = state.places.routes[name];
const { activeTicket } = state.places;
const trainInfo = activeTicket.trainsInfo.find((info) => {
return info.routeName === name;
});
return trainInfo.trainInfo.seatsTrainInfo.filter((coach) => {
return coach.coach.class_type === carriageType;
});
};
const useActiveInfo = (dir: string) => {
const routeName = mapDirToRoot(dir);
const selectActiveCoaches = handlerActiveCoaches(routeName);
const coaches = useAppSelector(selectActiveCoaches);
return coaches;
};
Eventually, if the first one works ok then the second one gives a lot of useless re-renders in component. I suspect that there are problems with selectActiveCoaches closure, maybe react considers that this selector is different on every re-render but I am wrong maybe. Could you explain how does it work?
Upvotes: 0
Views: 1275
Reputation: 67459
selectActiveCoaches
finishes with return seatsTrainInfo.filter()
. This always returns a new array reference, and useSelector
will force your component to re-render whenever your selector returns a different reference than last time. So, you are forcing your component to re-render after every dispatched action:
https://react-redux.js.org/api/hooks#equality-comparisons-and-updates
One option here would be to rewrite this as a memoized selector with Reselect:
https://redux.js.org/usage/deriving-data-selectors
Upvotes: 1