如何在 next.js 应用程序中添加主题提供程序?

tei*_*lai 5 provider themes web reactjs next.js

我想将 themeprovider 添加到我的应用程序中,以便我可以轻松地在深色和浅色模式之间切换

这就是我的layout.tsx的样子:

import "./globals.css";
import "@/styles/nav.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { ApolloProvider } from "@apollo/client";
import createApolloClient from "./apollo";
import Header from "./header";
import { ThemeProvider } from "styled-components";
import { darkTheme } from "@/styles/ThemeConfig";

const inter = Inter({ subsets: ["latin"] });
const client = createApolloClient();

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ThemeProvider theme={darkTheme}>
          <Header></Header>
          {children}
        </ThemeProvider>
      </body>
    </html>
  );
}

Run Code Online (Sandbox Code Playgroud)

我收到错误:服务器错误错误:createContext 仅适用于客户端组件。在文件顶部添加“use client”指令以使用它。了解更多: https: //nextjs.org/docs/messages/context-in-server-component

如果我将使用客户端添加到layout.tsx,我的页面仍然无法工作,并且出现其他错误无法编译./src\app\layout.tsx ReactServerComponentsError:

您正在尝试从标有“使用客户端”的组件导出“元数据”,这是不允许的。删除导出或“使用客户端”指令。阅读更多:https ://nextjs.org/docs/getting-started/react-essentials#the-use-client-directive

如何添加主题提供者?

import { createGlobalStyle } from "styled-components";

export const lightTheme = {
  body: "#FFF",
  text: "#363537",
  toggleBorder: "#FFF",
  background: "#363537",
};

export const darkTheme = {
  body: "#363537",
  text: "#FAFAFA",
  toggleBorder: "#6B8096",
  background: "#999",
};

export const GlobalStyles = createGlobalStyle`
  body {
    background: ${({ theme }) => theme.body};
    color: ${({ theme }) => theme.text};
    font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif;
    transition: all 0.50s linear;
  }
`;

Run Code Online (Sandbox Code Playgroud)

Rob*_*mas 7

您收到错误:

服务器错误错误:createContext 仅适用于客户端组件。在文件顶部添加“use client”指令以使用它。阅读更多:

https://nextjs.org/docs/messages/context-in-server-component

因为ThemeProvider应该在客户端运行(即客户端组件)。Next.js 中的所有客户端组件都需要使用"use client"指令进行标记。

由于您的ThemeProvider组件来自styled-components,这意味着您不能将其标记为"use client"


下一个选项是作为RootLayout客户端组件。但,

根布局默认是服务器组件,不能设置为客户端组件。

https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#layouts

所以你也不能"use client"添加。src/app/layout.tsx


这意味着唯一的选择是创建另一个组件(这将是客户端组件)并且您需要ThemeProvider在其中使用。然后在RootLayout.

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <ThemeClient>
          <Header></Header>
          {children}
        </ThemeClient>
      </body>
    </html>
  );
}
Run Code Online (Sandbox Code Playgroud)
"use client"

import { darkTheme } from "@/styles/ThemeConfig";

export default function ThemeClient({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <ThemeProvider theme={darkTheme}>
      {children}
    </ThemeProvider>
  )
} 
Run Code Online (Sandbox Code Playgroud)