-
I am using the following pattern in my project. The motivation here is that I re-use each of these variables enough that it's annoying to extract them to their own selector hooks. export const useGamesQuery = () => {
/* Queries */
const { currentSession } = useSessionsQuery();
const query = useSessionGamesQuery(currentSession?.id);
const sessionGames = query.data;
/* Games */
// note: sessionGames will never be very large, so these are cheap
const completedGames = sessionGames.filter(game => game.status === "complete");
const activeGames = sessionGames.filter(game => game.status === "playing");
const startedGames = sessionGames.filter(game => game.status === "playing" || game.status === "complete");
const upcomingGames = sessionGames.filter(game => ["purchasable", "waiting"].includes(game.status));
const nextGame = upcomingGames[0] || null;
const liveGame = activeGames[0] || null;
const previousGame = completedGames[completedGames.length - 1] || null;
/* Results */
// note: yes it is silly that visibleResults is coupled directly to each game
// ..... but that isn't up to me unfortunately :)
const liveResults = liveGame?.visibleResults || [];
// EXPENSIVE but memoized (uses setTimeout and complex logic)
const visibleResults = useVisibleResults(liveResults);
return {
...query,
derived: {
sessionGames,
activeGames,
startedGames,
upcomingGames,
nextGame,
liveGame,
previousGame,
completedGames,
visibleResults,
}
}
} I'm guessing it is probably sub-optimal to intertwine "results" and "games" like this, as any component subscribed to i.e. "upcomingGames" will re-render every time "liveResults" changes. But all derived "games" data will update with every change to "sessionGames" so it should not be a problem to couple them together. My gut tells me the best solution is to extract the results to its own hook like so: export const useResultsQuery = () => {
const { derived: { liveGame }, ...query } = useGamesQuery();
/* Results */
const liveResults = liveGame?.visibleResults || [];
const visibleResults = useVisibleResults(liveResults);
return {
...query,
data: visibleResults,
};
} But does this significantly lose out to taking advantage of |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
select is mainly a render optimization because it runs outside of react, and if nothing changed, it won't start rendering. If you don't have a problem of running too many renders, it's fine to not use it. |
Beta Was this translation helpful? Give feedback.
select is mainly a render optimization because it runs outside of react, and if nothing changed, it won't start rendering. If you don't have a problem of running too many renders, it's fine to not use it.