在 NextJS 13 中,我知道那些与 React context API 一起使用的提供程序只能在客户端组件中呈现。我还知道客户端组件中的组件(子组件或导入的组件)将被“视为客户端捆绑包的一部分。”,我认为这意味着它们将在客户端上呈现?
在 docs 中,它说要使用上下文提供程序,您应该创建一个客户端组件来呈现您的提供程序,并将需要访问提供程序的组件作为子组件,例如
'use client'
import { createContext } from 'react'
export const ThemeContext = createContext({})
export default function ThemeProvider({ children }) {
return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider>
}
如果这样做,是否意味着可以访问提供者的所有内容都将在客户端上渲染,从而抵消了 NextJS 通过服务器端渲染提供的大部分性能优势?该文档显示了上述代码的示例用法,并附有注释:
import ThemeProvider from './theme-provider'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<body>
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>
)
}
注意 ThemeProvider 如何仅包装 {children} 而不是整个 文档。这使得 Next.js 可以更轻松地优化服务器组件的静态部分。
ThemeProvider 仅包装 {children} 而不是整个文档的相关性是什么?这如何让 Next.js 更轻松地优化服务器组件的静态部分?在主题提供程序之外但在 html/body 标记内有任何组件不是不太可能/很少见吗?我很难理解文档中的这些示例是否是有利于高效渲染的好示例,或者如果您迫切需要使用某个 api(例如上下文提供程序),它们是否是最后的手段。
SSR 的性能优势来自于能够在初始加载时向客户端提供完全渲染的 HTML 页面,而不是在用户与页面交互之前等待一组 JavaScript 下载、解析和执行。即使某些组件是在客户端渲染的,只要页面的大部分是服务器渲染的并且可以快速交付,您仍然可以获得 SSR 的好处。
在典型的应用程序中,大多数组件可能位于某种提供程序中,例如 ThemeProvider 或 Redux StoreProvider。但这并不意味着它们都必须由客户端渲染。 您可以在提供者内部拥有服务器组件,只要它们不直接使用上下文。