我一直在努力实现 www.example.com 个js应用程序,并且遇到了一些问题,我一直很难破译的来源,所以我想我会扣除我的代码的绝对基础,并慢慢开始添加片段,直到我弄清楚。我已经这么做了,结果只会让人更困惑。
我将socket保存在一个上下文提供程序中,它是根布局文件中body
标记的直接子文件,所以它会 Package 我的整个应用程序(我使用socket的问题是,我不断得到无限的“连接完成”事件。我会在控制台上记录连接的时间,并且每隔几秒钟就会有一个新的连接。因此,将其作为主要父对象似乎是消除重新渲染的任何外部原因的最佳方法)。
无论如何,在我的上下文提供程序中,我已经剥离了与任何事情有关的所有内容,因此我可以按照我的“计划”慢慢添加内容。
这是我的布局文件:
import { SocketProvider } from "../hooks/useSocket";
import "./globals.css";
export const metadata = {
title: "Title",
description: "Description",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<SocketProvider>
<>{children}</>
</SocketProvider>
</body>
</html>
);
}
这是我的主页:
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export default function Home() {
return (
<main className="relative h-full flex-grow">
<p>empty page</p>
</main>
);
}
这是我的context provider:
"use client";
import React, {
createContext,
useContext,
useEffect,
} from "react";
type SocketContextProps = {
};
const SocketContext = createContext<SocketContextProps>({
});
export const SocketProvider = ({ children }: { children: JSX.Element }) => {
console.log(
"******************* render socket provider *******************"
);
useEffect(() => {
console.log(
"******************* socket provider useEffect *******************"
);
}, []);
return (
<SocketContext.Provider value={{}}>
{children}
</SocketContext.Provider>
);
};
export default function useSocket() {
return useContext(SocketContext);
}
问题:我得到这个日志"******************* render socket provider *******************"
打印3次
此日志******************* socket provider useEffect *******************
甚至一次也未打印
编辑:所以我决定在我的根(主页)页面中添加一个useEffect,看看它是否能帮助我更好地理解任何东西。此useEffect也未运行!
这是我的新主页:
"use client";
import { useEffect } from "react";
export default function GameHome() {
console.log("^^^^^^^ Home Page ^^^^^^^^^");
useEffect(() => {
console.log("$$$$$$$$ Home page useEffect $$$$$$$$$$");
}, []);
return (
<main className="relative h-full flex-grow">
<p>empty page</p>
</main>
);
}
这是我在控制台里得到的
wait - compiling...
wait - compiling /[game-slug]/page (client and server)...
event - compiled client and server successfully in 6.1s (634 modules)
******************* render socket provider *******************
******************* render socket provider *******************
^^^^^^^ Home Page ^^^^^^^^^
******************* render socket provider *******************
1条答案
按热度按时间wpx232ag1#
NextJS让你可以控制是在浏览器上还是在服务器上运行代码。当它在API文件夹下时很简单,因为它总是在服务器上,但当谈论React组件时很复杂。
默认情况下,nextJS是一个混合体,其中有CSR(客户端渲染,又名浏览器)和SSR(服务器端渲染,在这种情况下,是您的控制台)。它预先呈现react组件,执行所有与生命周期无关的代码。所以换句话说,在将其运送给用户之前,尽可能多地做。
由于useEffect是生命周期方法,因此它不会在服务器上执行,而是与执行它的浏览器所需的HTML和CSS一起运送。
如果你想运行服务器端逻辑,我建议你使用API文件夹。如果你想在UI组件中拥有它,幸运的是NextJS给了你一些控制!我建议你阅读以下阅读,因为他们比我更好地解释了这一点:
渲染的NextJS基础:https://beta.nextjs.org/docs/rendering/fundamentals
使SSG或SSR工作的基本特征:https://nextjs.org/docs/basic-features/pages
服务器端和客户端组件(很可能是未来的方式):https://beta.nextjs.org/docs/rendering/server-and-client-components