NextJS 13 错误/错误:createContext 仅适用于客户端组件。在文件顶部添加“use client”指令即可使用它

问题描述 投票:0回答:2

**错误:createContext 仅适用于客户端组件。在文件顶部添加“use client”指令以使用它。 ** 你能告诉我为什么会出现这个错误吗?

// layout.tsx
import Layout from "./components/common/Layout";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <Layout>{children}</Layout>
      </body>
    </html>
  );
}

// Layout.tsx

"use client";

import React, { useState, ReactNode } from "react";
import Nav from "@app/components/common/Nav";
import { Global, css } from "@emotion/react";
import { PageContextProvider } from "store/pageContext";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

export default function Layout({ children }: { children: ReactNode }) {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            refetchOnWindowFocus: false,
            staleTime: 5000,
          },
        },
      })
  );
  return (
    <div>
      <QueryClientProvider client={queryClient}>
        <Global styles={reset} />
        <PageContextProvider>
          <Nav />
          <div>{children}</div>
        </PageContextProvider>
      </QueryClientProvider>
    </div>
  );
}
// pageContext.tsx

"use client";

import React, { createContext, useState, useRef } from "react";

interface PageContextType {
  currentPage: number;
  setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
  sectionsRef: React.MutableRefObject<(HTMLElement | null)[]>;
}

export const PageContext = createContext<PageContextType>({
  currentPage: 0,
  setCurrentPage: () => {},
  sectionsRef: {} as React.MutableRefObject<(HTMLElement | null)[]>,
});

export const PageContextProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const [currentPage, setCurrentPage] = useState<number>(0);
  const sectionsRef = useRef<(HTMLDivElement | null)[]>([]);

  return (
    <PageContext.Provider value={{ currentPage, setCurrentPage, sectionsRef }}>
      {children}
    </PageContext.Provider>
  );
};

我想使用layout.tsx文件作为服务器组件并添加元数据,但是如果我在布局文件中不使用“使用客户端”,则会出现错误。你有认识的人吗?

javascript reactjs typescript next.js
2个回答
1
投票

您可以将

QueryClient
的 init 移动到单独的组件中(其中将包含
use client
),将其导入布局组件中并删除其中的
use client
。 这样你的布局组件将成为一个服务器组件。


0
投票

我上面的用户是对的,它最终应该看起来像这样

首先为提供者创建一个单独的组件:

src/components/ReactQueryClientProvider.tsx

内容:

"use client"

import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { useState } from "react"

export const ReactQueryClientProvider = ({ children }: { children: React.ReactNode }) => {
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            // With SSR, we usually want to set some default staleTime
            // above 0 to avoid refetching immediately on the client
            staleTime: 60 * 1000,
          },
        },
      })
  )
  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}

然后在你的根布局

src/app/layout.tsx
中,包装你的QueryClientProvider:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { ReactQueryClientProvider } from "@/components/ReactQueryClientProvider";

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

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

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <ReactQueryClientProvider>
      <html lang="en">
        <body className={inter.className}>{children}</body>
      </html>
    </ReactQueryClientProvider>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.