|
1 | | -import type { |
2 | | - InferActivityParams, |
3 | | - RegisteredActivityName, |
4 | | -} from "@stackflow/config"; |
5 | | -import { useCallback } from "react"; |
| 1 | +import { useMemo } from "react"; |
6 | 2 | import { useActivityComponentMap } from "./ActivityComponentMapProvider"; |
7 | | -import { |
8 | | - getContentComponent, |
9 | | - isStructuredActivityComponent, |
10 | | -} from "./StructuredActivityComponentType"; |
11 | 3 | import { useDataLoader } from "./loader"; |
| 4 | +import { makePrepare } from "./makePrepare"; |
| 5 | +import type { Prepare } from "./Prepare"; |
12 | 6 | import { useConfig } from "./useConfig"; |
13 | 7 |
|
14 | | -export type Prepare = <K extends RegisteredActivityName>( |
15 | | - activityName: K, |
16 | | - activityParams?: InferActivityParams<K>, |
17 | | -) => Promise<void>; |
18 | | - |
| 8 | +/** |
| 9 | + * `stackflow()` 출력의 `prepare`와 동일 로직을 감싸는 얇은 래퍼. |
| 10 | + * |
| 11 | + * React Context에서 파생되는 세 입력(`config`, `loadData`, `activityComponentMap`)을 |
| 12 | + * `makePrepare`에 그대로 넘긴다. 셋 중 하나라도 바뀌지 않는 한 반환 함수의 참조가 |
| 13 | + * 안정적이도록 메모이즈한다. |
| 14 | + */ |
19 | 15 | export function usePrepare(): Prepare { |
20 | 16 | const config = useConfig(); |
21 | 17 | const loadData = useDataLoader(); |
22 | 18 | const activityComponentMap = useActivityComponentMap(); |
23 | 19 |
|
24 | | - return useCallback( |
25 | | - async function prepare<K extends RegisteredActivityName>( |
26 | | - activityName: K, |
27 | | - activityParams?: InferActivityParams<K>, |
28 | | - ) { |
29 | | - const activityConfig = config.activities.find( |
30 | | - ({ name }) => name === activityName, |
31 | | - ); |
32 | | - const prefetchTasks: Promise<unknown>[] = []; |
33 | | - |
34 | | - if (!activityConfig) |
35 | | - throw new Error(`Activity ${activityName} is not registered.`); |
36 | | - |
37 | | - if (activityParams && activityConfig.loader) { |
38 | | - prefetchTasks.push( |
39 | | - Promise.resolve(loadData(activityName, activityParams)), |
40 | | - ); |
41 | | - } |
42 | | - |
43 | | - if ("_load" in activityComponentMap[activityName]) { |
44 | | - prefetchTasks.push( |
45 | | - Promise.resolve(activityComponentMap[activityName]._load?.()), |
46 | | - ); |
47 | | - } |
48 | | - |
49 | | - if ( |
50 | | - isStructuredActivityComponent(activityComponentMap[activityName]) && |
51 | | - typeof activityComponentMap[activityName].content === "function" |
52 | | - ) { |
53 | | - prefetchTasks.push( |
54 | | - getContentComponent(activityComponentMap[activityName]).preload(), |
55 | | - ); |
56 | | - } |
57 | | - |
58 | | - await Promise.all(prefetchTasks); |
59 | | - }, |
| 20 | + return useMemo( |
| 21 | + () => makePrepare({ config, loadData, activityComponentMap }), |
60 | 22 | [config, loadData, activityComponentMap], |
61 | 23 | ); |
62 | 24 | } |
0 commit comments