**错误: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文件作为服务器组件并添加元数据,但是如果我在布局文件中不使用“使用客户端”,则会出现错误。你有认识的人吗?
您可以将
QueryClient
的 init 移动到单独的组件中(其中将包含 use client
),将其导入布局组件中并删除其中的 use client
。
这样你的布局组件将成为一个服务器组件。
我上面的用户是对的,它最终应该看起来像这样
首先为提供者创建一个单独的组件:
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>
);
}