如何在 _document.js 和 Next.js 上的页面之间共享 React 上下文?
How to share React context between _document.js and pages on Next.js?
假设我有这个上下文:
export const ThemeContext = createContext();
export function ThemeWrapper({ children }) {
const sharedState = {
darkMode: false,
};
return (
<ThemeContext.Provider value={sharedState}>
{children}
</ThemeContext.Provider>
);
}
export function useThemeContext() {
return useContext(ThemeContext);
}
我可以像这样在 _document.js
上访问:
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ThemeWrapper, ThemeContext } from "../context/theme";
class MyDocument extends Document {
static contextType = ThemeContext;
render() {
console.log("theme", this.context);
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
class Wrapped extends Document {
render() {
return (
<ThemeWrapper>
<MyDocument />
</ThemeWrapper>
);
}
}
export default Wrapped;
现在我也想从一个页面访问这个上下文:
import { useThemeContext } from "../context/theme";
const SomePage = () => {
const theme = useThemeContext();
console.log("theme", theme);
return (
<div>Hi, I'm a page</div>
);
};
首次加载页面时,_document.js
在 Next.js 控制台上注销 theme { darkMode: false }
但 SomePage
在 Chrome 上注销 theme undefined
] 控制台每次导航到它。
有什么建议吗?
我需要根据上下文在 html
标签上切换一些 class。正在尝试 manually toggle dark mode using Tailwind CSS.
用 ThemeWrapper
包装 _document
不会让您访问页面内的上下文(可能是因为 it's only rendered in the server),您需要为此包装 _app
.请注意,_document
不会在上下文状态更改时重新呈现。
对于这个特定的用例,另一种方法是使用 next-themes
.
假设我有这个上下文:
export const ThemeContext = createContext();
export function ThemeWrapper({ children }) {
const sharedState = {
darkMode: false,
};
return (
<ThemeContext.Provider value={sharedState}>
{children}
</ThemeContext.Provider>
);
}
export function useThemeContext() {
return useContext(ThemeContext);
}
我可以像这样在 _document.js
上访问:
import Document, { Html, Head, Main, NextScript } from "next/document";
import { ThemeWrapper, ThemeContext } from "../context/theme";
class MyDocument extends Document {
static contextType = ThemeContext;
render() {
console.log("theme", this.context);
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
class Wrapped extends Document {
render() {
return (
<ThemeWrapper>
<MyDocument />
</ThemeWrapper>
);
}
}
export default Wrapped;
现在我也想从一个页面访问这个上下文:
import { useThemeContext } from "../context/theme";
const SomePage = () => {
const theme = useThemeContext();
console.log("theme", theme);
return (
<div>Hi, I'm a page</div>
);
};
首次加载页面时,_document.js
在 Next.js 控制台上注销 theme { darkMode: false }
但 SomePage
在 Chrome 上注销 theme undefined
] 控制台每次导航到它。
有什么建议吗?
我需要根据上下文在 html
标签上切换一些 class。正在尝试 manually toggle dark mode using Tailwind CSS.
用 ThemeWrapper
包装 _document
不会让您访问页面内的上下文(可能是因为 it's only rendered in the server),您需要为此包装 _app
.请注意,_document
不会在上下文状态更改时重新呈现。
对于这个特定的用例,另一种方法是使用 next-themes
.