H3l*_*nik 19 reactjs next.js next.js13
我写了一个如下所示的组件:
'use client'
export const HorizontalModule = (props: any) => {
...
return (
{scrollPosition >= 0 && (
<FirstModule />
)}
{scrollPosition >= window.innerHeight * 2 && (
<SecondModule />
)}
)
})
Run Code Online (Sandbox Code Playgroud)
但我收到“窗口未定义”错误。
阅读不同的帖子,我发现大多数人发现使用动态导入很有用,所以我在父组件(即 nextjs 页面)中执行此操作:
const HorizontalModule = dynamic<any>(
() => import('./HorizontalModule/HorizontalModule').then((mod) => mod.HorizontalModule),
{
ssr: false,
suspense: true,
loading: () => <p>Loading...</p>
}
)
Run Code Online (Sandbox Code Playgroud)
起初我收到此错误:“对象不是函数”
现在我收到“不支持的服务器组件类型:未定义”
我不完全知道我做了什么来切换错误,但它仍然不起作用。
我必须提到,我在 HorizontalModule 代码中使用了窗口对象,但当useEffects我在渲染函数中使用它时,所有的都停止工作。
我还尝试在组件内部编写如下验证:
if (window === undefined) return (<></>)
return (...)
Run Code Online (Sandbox Code Playgroud)
我得到了相同的窗口未定义对象或水合错误。
我不知道还有什么可做的,ssr false不起作用,悬念也,窗口条件......
Chr*_*ton 29
来自 Next.js 13 文档:https://beta.nextjs.org/docs/rendering/server-and-client-components#client-components
[客户端组件] 在服务器上预渲染并在客户端上进行水化。
因此该'use client'指令不会完全在客户端上呈现页面。它仍然会在服务器上执行组件代码,就像 Next.js 12 及以下版本中一样。window当使用服务器上不可用的东西时,您需要考虑到这一点。
您不能只检查窗口是否已定义,然后立即在客户端上更新,因为这可能会导致服务器预渲染和客户端初始渲染之间不匹配(也称为水合错误)。
要在客户端加载时更新页面,您需要结合使用useEffecthook 和useStatehook。由于useEffect在初始渲染期间执行,因此状态更新直到下一次渲染才会生效。因此,第一个渲染与预渲染匹配 - 没有水合错误。更多信息在这里: https: //nextjs.org/docs/messages/react-Hydration-error
您无需在每个需要它的组件中创建此机制,而是可以创建一个仅使用 using 设置布尔值的上下文useEffect,告诉我们可以安全地执行客户端代码。
is-客户端-ctx.jsx
const IsClientCtx = createContext(false);
export const IsClientCtxProvider = ({ children }) => {
const [isClient, setIsClient] = useState(false);
useEffect(() => setIsClient(true), []);
return (
<IsClientCtx.Provider value={isClient}>{children}</IsClientCtx.Provider>
);
};
export function useIsClient() {
return useContext(IsClientCtx);
}
Run Code Online (Sandbox Code Playgroud)
_app.jsx
function MyApp({ Component, pageProps }) {
return (
<IsClientCtxProvider>
<Component {...pageProps} />
</IsClientCtxProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
用法
const isClient = useIsClient();
return (
<>
{scrollPosition >= 0 && <FirstModule />}
{isClient && scrollPosition >= window.innerHeight * 2 && <SecondModule />}
</>
);
Run Code Online (Sandbox Code Playgroud)
现场演示:https://stackblitz.com/edit/nextjs-mekkqj? file=pages/index.tsx
| 归档时间: |
|
| 查看次数: |
16229 次 |
| 最近记录: |