英文:
Is it normal that all components in Next.js are client components?
问题
以下是翻译好的部分:
我有一个Next应用程序。我使用应用程序文件夹和Next Auth库。为了使每个页面都能访问会话,我将整个应用程序包装在SessionProvider
中。但由于它在底层使用了useContext
,我不得不在每个地方添加'use client'
指令。这导致所有页面都变成了客户端渲染,因为它们使用了useSession
。并且所有页面组件(按钮、输入)也变成了客户端渲染。
app/layout.tsx
const RootLayout = ({ session, children }: { session: Session; children: ReactNode }) => {
return (
<SessionProvider session={session}>
<html lang={`eng`} >
<head>
</head>
<body>
{children}
</body>
</html>
</SessionProvider>
)
}
一些受保护的页面
'use client';
import { useSession } from "next-auth/react";
export default function ProtectedPage() {
const { data, status } = useSession()
return (
<div>
{status === "authenticated" ? <div>{data.name}</div> : null}
</div>
)
}
所有页面和组件现在都在客户端渲染是否正常?Next Auth文档建议将所有内容都包装在提供程序中,但这样一来,Next.js的主要功能,即SSR,就不再起作用。
英文:
I have a Next app. I use app folder and Next Auth library. So that each page has access to the session, I wrapped the entire application in a SessionProvider
. But since it's useContext
under the hood, I had to add the 'use client'
directive everywhere. This resulted in all pages being client-side since they use useSession
. And all page components (buttons, inputs) also became client-side.
app/layout.tsx
const RootLayout = ({ session, children }: { session: Session; children: ReactNode }) => {
return (
<SessionProvider session={session}>
<html lang={`eng`}
<head>
</head>
<body>
{children}
</body>
</html>
</SessionProvider>
)
}
some protected page
'use client';
import {useSession} from "next-auth/react";
export default function ProtectedPage() {
const {data, status} = useSession()
return (
<div>
{status === "authenticated" ? <div>data.name</div> : null}
</div>
)
}
Is it normal that all pages and components are now rendered on the client? The Next Auth documentation recommends wrapping everything in a provider, but then the main feature of Next.js, namely SSR, no longer works
答案1
得分: 3
> 在Next.js中,所有组件都是客户端组件是正常的吗?
app文件夹下的每个组件默认都是服务器组件,意味着它在服务器端呈现,并且其代码保留在服务器端。
使用use client
> 所有页面和组件现在都在客户端上呈现是正常的吗?
您可以将服务器组件混合在客户端组件中作为其子组件。
<ClientComponent>
<ServerComponent />
</ClientComponent>
有关更多详细信息,请阅读dev.to上的这篇文章。
您可能还会对阅读medium上的这篇博客感兴趣。
英文:
> Is it normal that all components in Next.js are client components?
Every component under the app folder is, by default, a server component, meaning that it's rendered on the server side, and its code stays on the server side.
With use client
> Is it normal that all pages and components are now rendered on the client?
You can mix server component in client component as its children.
<ClientComponent>
<ServerComponent />
</ClientComponent>
For further detail, read this article on dev.to.
You may also be interested to read this blog on medium.
答案2
得分: 1
以下是您要翻译的内容:
不,不是每个组件都需要成为客户端组件。您可以创建一个包装组件,它是一个客户端组件,接收子组件。服务器和客户端组件都可以作为子组件传递给客户端组件。
示例包装组件
"use client";
import NoAuthComponent from "components/NoAuthComponent";
interface Props extends React.PropsWithChildren {}
// 如果未经导入而作为属性提供未经身份验证的视图,您也可以将其设置为服务器组件
export default function ProtectedView({ children }: Props): JSX.Element {
const session = useSession();
if (session?.status !== "authenticated") return <NoAuthComponent />;
return <>{children}</>;
}
示例用法
import "server-only";
import ProtectedView from "components/ProtectedView";
import MyServerComponent from "components/MyServerComponent";
export default async function MyPage(): Promise<JSX.Element> {
const response = await fetch("...");
const data = await response.json();
return (
<ProtectedView>
<MyServerComponent data={data} />
</ProtectedView>
);
}
有关组合、嵌套和处理客户端和服务器组件的更多信息,请查看官方文档。
英文:
No, not every component needs to be a client component. You could create a wrapper component that is a client component which receives children. Both server and client components can be passed to client components as children.
Example wrapper component
"use client";
import NoAuthComponent from "components/NoAuthComponent";
interface Props extends React.PropsWithChildren {}
// if the no auth view was provided as a prop rather then
// imported you could also make it a server component
export default function ProtectedView({ children }: Props): JSX.Element {
const session = useSession();
if (session?.status !== "authenticated") return <NoAuthComponent />;
return <>{children}</>;
}
Example usage
import "server-only";
import ProtectedView from "components/ProtectedView";
import MyServerComponent from "components/MyServerComponent";
export default async function MyPage(): Promise<JSX.Element> {
const response = await fetch("...");
const data = await response.json();
return (
<ProtectedView>
<MyServerComponent data={data} />
</ProtectedView>
);
}
More information about composing, nesting and working with client and server components can be found inside the official documentation.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论