This commit is contained in:
@@ -1,19 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
|
||||
import {
|
||||
createContext,
|
||||
useContext,
|
||||
useSyncExternalStore,
|
||||
type ReactNode,
|
||||
} from "react";
|
||||
|
||||
import { syncPreferredLanguage } from "@/i18n";
|
||||
|
||||
const I18nHydrationContext = createContext(false);
|
||||
|
||||
function subscribeI18nHydration(onStoreChange: () => void): () => void {
|
||||
queueMicrotask(() => {
|
||||
syncPreferredLanguage();
|
||||
onStoreChange();
|
||||
});
|
||||
return () => {};
|
||||
}
|
||||
|
||||
function getI18nHydratedSnapshot(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getI18nHydratedServerSnapshot(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** hydration 完成前保持 DEFAULT_LANGUAGE,与 SSR 一致;完成后再同步用户偏好语言。 */
|
||||
export function I18nHydrationProvider({ children }: { children: ReactNode }) {
|
||||
const [hydrated, setHydrated] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
syncPreferredLanguage();
|
||||
setHydrated(true);
|
||||
}, []);
|
||||
const hydrated = useSyncExternalStore(
|
||||
subscribeI18nHydration,
|
||||
getI18nHydratedSnapshot,
|
||||
getI18nHydratedServerSnapshot,
|
||||
);
|
||||
|
||||
return (
|
||||
<I18nHydrationContext.Provider value={hydrated}>{children}</I18nHydrationContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user