diff --git a/package.json b/package.json index b791056..0a0f662 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,8 @@ "react-syntax-highlighter": "^15", "shiki-es": "^0.2", "use-merge-value": "^1", - "zustand": "^4" + "zustand": "^4", + "zustand-utils": "^1" }, "devDependencies": { "@commitlint/cli": "^17", diff --git a/src/components/StoreUpdater/index.tsx b/src/components/StoreUpdater/index.tsx index d0c33c3..5d6354a 100644 --- a/src/components/StoreUpdater/index.tsx +++ b/src/components/StoreUpdater/index.tsx @@ -10,7 +10,7 @@ import { } from 'dumi'; import isEqual from 'fast-deep-equal'; import React, { memo, useEffect } from 'react'; -import { SiteStore, useSiteStore } from '../../store/useSiteStore'; +import { SiteStore, useStoreApi } from '../../store/useSiteStore'; const isBrowser = typeof window !== 'undefined'; @@ -40,9 +40,10 @@ const useSyncState = ( value: SiteStore[T], updateMethod?: (key: T, value: SiteStore[T]) => void, ) => { + const storeApi = useStoreApi(); const updater = updateMethod ? updateMethod - : (key: T, value: SiteStore[T]) => useSiteStore.setState({ [key]: value }); + : (key: T, value: SiteStore[T]) => storeApi.setState({ [key]: value }); // 如果是 Node 环境,直接更新一次 store // 但是为了避免多次更新 store,所以加一个标记 @@ -70,6 +71,7 @@ export const StoreUpdater = memo(() => { const navData = useNavData(); const location = useLocation(); const locale = useLocale(); + const storeApi = useStoreApi(); useSyncState('siteData', siteData, () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -77,11 +79,11 @@ export const StoreUpdater = memo(() => { const { // eslint-disable-next-line @typescript-eslint/no-unused-vars siteData: { setLoading: _, ...prevData }, - } = useSiteStore.getState(); + } = storeApi.getState(); if (isEqual(data, prevData)) return; - useSiteStore.setState({ siteData }); + storeApi.setState({ siteData }); }); useSyncState('sidebar', sidebar); @@ -93,7 +95,7 @@ export const StoreUpdater = memo(() => { useSyncState('navData', navData, () => { const data = siteData.themeConfig.hideHomeNav ? navData : [homeNav, ...navData]; - useSiteStore.setState({ navData: data }); + storeApi.setState({ navData: data }); }); return null; diff --git a/src/layouts/DocLayout/index.tsx b/src/layouts/DocLayout/index.tsx index 5c8e885..8bf8841 100644 --- a/src/layouts/DocLayout/index.tsx +++ b/src/layouts/DocLayout/index.tsx @@ -1,5 +1,15 @@ import { extractStaticStyle } from 'antd-style'; -import { Helmet, useIntl, useLocation } from 'dumi'; +import { + Helmet, + useIntl, + useLocale, + useLocation, + useNavData, + useRouteMeta, + useSidebarData, + useSiteData, + useTabMeta, +} from 'dumi'; import isEqual from 'fast-deep-equal'; import { PropsWithChildren, memo, useEffect, type FC } from 'react'; @@ -9,7 +19,7 @@ import { StoreUpdater } from '../../components/StoreUpdater'; import Docs from '../../pages/Docs'; import Home from '../../pages/Home'; -import { isHeroPageSel, tokenSel, useSiteStore } from '../../store'; +import { Provider, createStore, isHeroPageSel, tokenSel, useSiteStore } from '../../store'; import { GlobalStyle } from './styles'; const DocLayout: FC = memo(() => { @@ -64,12 +74,26 @@ const ThemeProvider = ({ children }: PropsWithChildren) => { ); }; -export default () => ( - <> - - - - - - -); +export default () => { + const siteData = useSiteData(); + const sidebar = useSidebarData(); + const routeMeta = useRouteMeta(); + const tabMeta = useTabMeta(); + const navData = useNavData(); + const location = useLocation(); + const locale = useLocale(); + + return ( + + createStore({ siteData, navData, locale, location, routeMeta, tabMeta, sidebar }) + } + > + + + + + + + ); +}; diff --git a/src/store/useSiteStore.ts b/src/store/useSiteStore.ts index 40cb018..ed1a922 100644 --- a/src/store/useSiteStore.ts +++ b/src/store/useSiteStore.ts @@ -12,7 +12,8 @@ import { PICKED_PKG_FIELDS } from 'dumi/dist/constants'; import type { Location } from 'history'; import { ComponentType } from 'react'; -import { create } from 'zustand'; +import { create, StoreApi } from 'zustand'; +import { createContext } from 'zustand-utils'; import { devtools } from 'zustand/middleware'; export type NavData = (INavItem & { children?: INavItem[] | undefined })[]; @@ -81,11 +82,16 @@ const initialState: SiteStore = { locale: { id: 'zh-CN', name: '中文', suffix: '' }, }; -export const useSiteStore = create()( - devtools( - () => ({ - ...initialState, - }), - { name: 'dumi-theme-antd-style' }, - ), -); +export const createStore = (initState: SiteStore) => + create()( + devtools( + () => ({ + ...initialState, + ...initState, + }), + { name: 'dumi-theme-antd-style' }, + ), + ); + +const { useStore, useStoreApi, Provider } = createContext>(); +export { useStore as useSiteStore, Provider, useStoreApi };