如何在 _document.js 和 Next.js 页面之间共享 React 上下文?

Cam*_*ilo 2 javascript reactjs next.js tailwind-css

假设我有这样的背景:

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);
}
Run Code Online (Sandbox Code Playgroud)

_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;
Run Code Online (Sandbox Code Playgroud)

现在我还想从页面访问此上下文:

import { useThemeContext } from "../context/theme";

const SomePage = () => {
  const theme = useThemeContext();

  console.log("theme", theme);

  return (
    <div>Hi, I'm a page</div>
  );
};
Run Code Online (Sandbox Code Playgroud)

_document.jstheme { darkMode: false }首次加载页面时会在 Next.js 控制台上注销,但每次导航到该页面时都会在 Chrome 控制台上SomePage注销。theme undefined

有什么建议么?

我需要html根据上下文切换标签上的一些类。尝试使用 Tailwind CSS 手动切换暗模式

eno*_*och 6

_documentThemeWrapper不允许您访问页面内的上下文(可能是因为它仅在服务器中呈现),您需要换行_app。请注意,_document不会在上下文状态更改时重新渲染。

对于这个特定的用例,另一种方法是使用next-themes.