Skip to content

Commit

Permalink
🐛 fix: 修正首屏 SSR 的内容不正确的 bug (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx authored Jul 20, 2023
1 parent 7dfeade commit 8a14b12
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 58 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

### [Version 0.29.3-alpha.1](https://github.com/arvinxx/dumi-theme-antd-style/compare/v0.29.2...v0.29.3-alpha.1)

<sup>Released on **2023-07-20**</sup>

#### 🐛 修复

- 修正首屏 SSR 的内容不正确的 bug.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's fixed

- 修正首屏 SSR 的内容不正确的 bug ([1c408cf](https://github.com/arvinxx/dumi-theme-antd-style/commit/1c408cf))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>

### [Version&nbsp;0.29.2](https://github.com/arvinxx/dumi-theme-antd-style/compare/v0.29.1...v0.29.2)

<sup>Released on **2023-07-20**</sup>
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dumi-theme-antd-style",
"version": "0.29.2",
"version": "0.29.3-alpha.1",
"description": "dumi-theme-antd-style 是为 dumi2 打造的一款文档站主题包,提供了更加美观、易用的研发与阅读体验",
"keywords": [
"npm",
Expand Down Expand Up @@ -74,7 +74,8 @@
"react-syntax-highlighter": "^15",
"shiki-es": "^0.2",
"use-merge-value": "^1",
"zustand": "^4"
"zustand": "^4",
"zustand-utils": "^1"
},
"devDependencies": {
"@commitlint/cli": "^17",
Expand Down
12 changes: 7 additions & 5 deletions src/components/StoreUpdater/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -40,9 +40,10 @@ const useSyncState = <T extends keyof SiteStore>(
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,所以加一个标记
Expand Down Expand Up @@ -70,18 +71,19 @@ 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
const { setLoading, ...data } = siteData;
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);
Expand All @@ -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;
Expand Down
41 changes: 34 additions & 7 deletions src/layouts/DocLayout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
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';
import { PropsWithChildren, memo, useEffect, useMemo, type FC } from 'react';

import DumiSiteProvider from '../../components/DumiSiteProvider';
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(() => {
Expand Down Expand Up @@ -64,12 +74,29 @@ const ThemeProvider = ({ children }: PropsWithChildren) => {
);
};

export default () => (
<>
const App = memo(({ initState }: any) => (
<Provider createStore={() => createStore(initState)}>
<StoreUpdater />
<ThemeProvider>
<GlobalStyle />
<DocLayout />
</ThemeProvider>
</>
);
</Provider>
));

export default () => {
const siteData = useSiteData();
const sidebar = useSidebarData();
const routeMeta = useRouteMeta();
const tabMeta = useTabMeta();
const navData = useNavData();
const location = useLocation();
const locale = useLocale();

const initState = useMemo(
() => ({ siteData, navData, locale, location, routeMeta, tabMeta, sidebar }),
[],
);

return <App initState={initState} />;
};
149 changes: 149 additions & 0 deletions src/store/selectors/hero.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { SiteStore } from '../useSiteStore';
import { localeValueSel } from './hero';

describe('localeValueSel', () => {
const s = {
locale: {
id: 'en',
name: 'English',
},
// Add other required properties for the test cases
} as SiteStore;

it('should return undefined when value is falsy', () => {
const value = null;

const result = localeValueSel(s, value);

expect(result).toBeUndefined();
});

it('should return value[s.locale.id] when it exists', () => {
const value = {
en: 'English value',
es: 'Spanish value',
};

const result = localeValueSel(s, value);

expect(result).toBe('English value');
});

it('should return value when value[s.locale.id] does not exist', () => {
const value = 'Default value';

const result = localeValueSel(s, value);

expect(result).toBe(value);
});

it('should return value[s.locale.id] for different locale.id values', () => {
const value = {
en: 'English value',
es: 'Spanish value',
};

const localeIds = ['en', 'es'];

localeIds.forEach((localeId) => {
const sWithLocaleId = {
...s,
locale: {
...s.locale,
id: localeId,
},
};

const result = localeValueSel(sWithLocaleId, value);

// @ts-ignore
expect(result).toBe(value[localeId]);
});
});

it('should return the correct value for different types of value', () => {
const values = ['String value', 123, [1, 2, 3], { key: 'value' }];

values.forEach((value) => {
const result = localeValueSel(s, value);

expect(result).toBe(value);
});
});

it('should return value when s.locale.id is falsy', () => {
const value = {
en: 'English value',
es: 'Spanish value',
};

const sWithFalsyLocaleId = {
...s,
locale: {
...s.locale,
id: null,
},
} as unknown as SiteStore;

const result = localeValueSel(sWithFalsyLocaleId, value);

expect(result).toBe(value);
});

it('should return value when s.locale.id is a string', () => {
const value = {
en: 'English value',
es: 'Spanish value',
};

const sWithStringLocaleId = {
...s,
locale: {
...s.locale,
id: 'en',
},
};

const result = localeValueSel(sWithStringLocaleId, value);

expect(result).toBe(value.en);
});

it('should return value when s.locale.id is a number', () => {
const value = {
1: 'One value',
2: 'Two value',
};

const sWithNumberLocaleId = {
...s,
locale: {
...s.locale,
id: 1,
},
} as unknown as SiteStore;

const result = localeValueSel(sWithNumberLocaleId, value);

expect(result).toBe(value[1]);
});

it('should return value when s.locale.id does not exist in value object', () => {
const value = {
en: 'English value',
es: 'Spanish value',
};

const sWithInvalidLocaleId = {
...s,
locale: {
...s.locale,
id: 'fr',
},
};

const result = localeValueSel(sWithInvalidLocaleId, value);

expect(result).toBe(value);
});
});
2 changes: 1 addition & 1 deletion src/store/selectors/hero.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SiteStore } from '../useSiteStore';

export const isHeroPageSel = (s: SiteStore) => !!s.routeMeta.frontmatter.hero;

const localeValueSel = (s: SiteStore, value: any) => {
export const localeValueSel = (s: SiteStore, value: any) => {
if (!value) return;

if (value[s.locale.id]) return value[s.locale.id];
Expand Down
49 changes: 6 additions & 43 deletions src/store/useSiteStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 })[];
Expand Down Expand Up @@ -46,46 +47,8 @@ export interface SiteStore {
locale: ILocale;
}

const initialState: SiteStore = {
siteData: {
// @ts-ignore
setLoading: undefined,
loading: true,
pkg: {},
components: {},
demos: {},
locales: [],
entryExports: {},
// @ts-ignore
themeConfig: {},
},
sidebar: [],
navData: [],
export const createStore = (initState: SiteStore) =>
create<SiteStore>()(devtools(() => initState, { name: 'dumi-theme-antd-style' }));

location: {
pathname: '',
state: '',
search: '',
hash: '',
key: '',
},

routeMeta: {
toc: [],
texts: [],
tabs: undefined,
// @ts-ignore
frontmatter: {},
},

locale: { id: 'zh-CN', name: '中文', suffix: '' },
};

export const useSiteStore = create<SiteStore>()(
devtools(
() => ({
...initialState,
}),
{ name: 'dumi-theme-antd-style' },
),
);
const { useStore, useStoreApi, Provider } = createContext<StoreApi<SiteStore>>();
export { useStore as useSiteStore, Provider, useStoreApi };

1 comment on commit 8a14b12

@vercel
Copy link

@vercel vercel bot commented on 8a14b12 Jul 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.