Skip to content

Commit 3c05a92

Browse files
committed
refactor(command): stabilize channel refs for task-channel map
Address review: memoize the derived `channels` array in useChannels so its reference is stable while the data is unchanged, and have useTaskChannelMap take channels as a parameter instead of opening a second useChannels subscription. Removes the duplicate subscription and the per-render Map rebuild that cascaded into taskSections recomputing. Generated-By: PostHog Code Task-Id: bc6e7269-db09-4ef7-b3a4-41f0ca03abaf
1 parent c84cab5 commit 3c05a92

3 files changed

Lines changed: 20 additions & 14 deletions

File tree

packages/ui/src/features/canvas/hooks/useChannels.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Schemas } from "@posthog/api-client";
22
import { useOptionalAuthenticatedClient } from "@posthog/ui/features/auth/authClient";
33
import { useAuthenticatedQuery } from "@posthog/ui/hooks/useAuthenticatedQuery";
44
import { useMutation, useQueryClient } from "@tanstack/react-query";
5-
import { useCallback } from "react";
5+
import { useCallback, useMemo } from "react";
66

77
const CHANNELS_POLL_INTERVAL_MS = 30_000;
88
const CHANNELS_QUERY_KEY = ["canvas-channels"] as const;
@@ -37,10 +37,16 @@ export function useChannels(options?: { enabled?: boolean }): {
3737
refetchInterval: CHANNELS_POLL_INTERVAL_MS,
3838
},
3939
);
40-
const channels = (query.data ?? [])
41-
.filter((fs) => fs.type === "folder")
42-
.map(toChannel)
43-
.sort((a, b) => a.name.localeCompare(b.name));
40+
// Memoize so the array reference is stable while the underlying data is
41+
// unchanged — callers depend on `channels` in their own memos/effects.
42+
const channels = useMemo(
43+
() =>
44+
(query.data ?? [])
45+
.filter((fs) => fs.type === "folder")
46+
.map(toChannel)
47+
.sort((a, b) => a.name.localeCompare(b.name)),
48+
[query.data],
49+
);
4450
return { channels, isLoading: query.isLoading };
4551
}
4652

packages/ui/src/features/canvas/hooks/useTaskChannelMap.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
import { useHostTRPC } from "@posthog/host-router/react";
2-
import {
3-
type Channel,
4-
useChannels,
5-
} from "@posthog/ui/features/canvas/hooks/useChannels";
2+
import type { Channel } from "@posthog/ui/features/canvas/hooks/useChannels";
63
import { useQueries } from "@tanstack/react-query";
74
import { useMemo } from "react";
85

@@ -12,12 +9,15 @@ import { useMemo } from "react";
129
* the mapping is unambiguous. Fans out one `channelTasks.list` query per
1310
* channel; results are shared with the channel sidebar's per-section queries
1411
* through the react-query cache.
12+
*
13+
* Takes the already-fetched `channels` rather than subscribing to `useChannels`
14+
* itself, so the caller owns the single subscription and a stable reference.
1515
*/
16-
export function useTaskChannelMap(options?: {
17-
enabled?: boolean;
18-
}): Map<string, Channel> {
16+
export function useTaskChannelMap(
17+
channels: Channel[],
18+
options?: { enabled?: boolean },
19+
): Map<string, Channel> {
1920
const enabled = options?.enabled ?? true;
20-
const { channels } = useChannels({ enabled });
2121
const trpc = useHostTRPC();
2222
const results = useQueries({
2323
queries: channels.map((channel) =>

packages/ui/src/features/command/CommandMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export function CommandMenu({ open, onOpenChange }: CommandMenuProps) {
9696
const closeSettingsDialog = closeSettings;
9797
const { folders } = useFolders();
9898
const { channels } = useChannels();
99-
const taskChannelMap = useTaskChannelMap({ enabled: open });
99+
const taskChannelMap = useTaskChannelMap(channels, { enabled: open });
100100
const { theme, setTheme } = useThemeStore();
101101
const toggleLeftSidebar = useSidebarStore((state) => state.toggle);
102102
const view = useAppView();

0 commit comments

Comments
 (0)