generated from arvinxx/npm-template
-
Notifications
You must be signed in to change notification settings - Fork 43
/
index.tsx
107 lines (91 loc) · 2.76 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { useDebounceEffect } from 'ahooks';
import {
useLocale,
useLocation,
useNavData,
useRouteMeta,
useSidebarData,
useSiteData,
useTabMeta,
} from 'dumi';
import isEqual from 'fast-deep-equal';
import React, { memo, useEffect } from 'react';
import { SiteStore, useStoreApi } from '../../store/useSiteStore';
const isBrowser = typeof window !== 'undefined';
const SSRInit: Record<string, boolean> = {};
const useReact18xUpdater = (effect: React.EffectCallback, deps?: React.DependencyList) => {
useEffect(() => {
(React as any).startTransition(() => {
effect();
});
}, deps);
};
const useLegacyUpdater = (effect: React.EffectCallback, deps?: React.DependencyList) => {
useDebounceEffect(
() => {
effect();
},
deps,
{ wait: 32, maxWait: 96 },
);
};
const useUpdater =
typeof (React as any).startTransition === 'function' ? useReact18xUpdater : useLegacyUpdater;
const useSyncState = <T extends keyof SiteStore>(
key: T,
value: SiteStore[T],
updateMethod?: (key: T, value: SiteStore[T]) => void,
) => {
const storeApi = useStoreApi();
const updater = updateMethod
? updateMethod
: (key: T, value: SiteStore[T]) => storeApi.setState({ [key]: value });
// 如果是 Node 环境,直接更新一次 store
// 但是为了避免多次更新 store,所以加一个标记
if (!isBrowser && !SSRInit[key]) {
updater(key, value);
SSRInit[key] = true;
}
useUpdater(() => {
updater(key, value);
}, [value]);
};
const displayLangHomeNavMap: Record<string, string> = {
'zh-CN': '首页',
'en-US': 'Home',
};
const getHomeNav = (id: string) => ({
title: displayLangHomeNavMap[id],
link: '/',
activePath: '/',
});
export const StoreUpdater = memo(() => {
const siteData = useSiteData();
const sidebar = useSidebarData();
const routeMeta = useRouteMeta();
const tabMeta = useTabMeta();
const navData = useNavData();
const location = useLocation();
const locale = useLocale();
const storeApi = useStoreApi();
useSyncState('siteData', siteData, () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { setLoading, ...data } = siteData;
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
siteData: { setLoading: _, ...prevData },
} = storeApi.getState();
if (isEqual(data, prevData)) return;
storeApi.setState({ siteData });
});
useSyncState('sidebar', sidebar);
useSyncState('routeMeta', routeMeta);
useSyncState('location', location);
useSyncState('tabMeta', tabMeta);
useSyncState('locale', locale);
useSyncState('navData', navData, () => {
const data = siteData.themeConfig.hideHomeNav ? navData : [getHomeNav(locale.id), ...navData];
storeApi.setState({ navData: data });
});
return null;
});