渲染静态网站时有条件的挂钩



我正在使用React static生成静态网站。使用新钩API中的useLayoutEffect,我在静态渲染阶段(与服务器端渲染相同的API)中获取此警告:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format.
  This will lead to a mismatch between the initial, non-hydrated UI and th  e intended UI.
  To avoid this, useLayoutEffect should only be used in components that render exclusively on the client.

当然这是有道理的。但是,当人们确定不会有任何不匹配时,摆脱此警告的好选择是什么?

在我的布局效果中,我只在body标签中添加了一些CSS,因此在客户端的水合阶段不会有任何不匹配(因为body不是React的业务)。

使用有条件钩子反应强烈禁止,但是在此非常特定的情况下,做类似:

的事情是没有意义的。
if(typeof window !== 'undefined')
  useLayoutEffect(() => {
      document.body.style.overflowY = loading ? 'hidden' : 'visible'
    },
    [loading]
  )

正确的方法是什么?

我认为您应该使用上下文将"隐藏/可见"值传递给其他组件。在这种情况下,呈现所有页面包装器的组件。

useEffect(() => { 
  fnSetContextValue(isLoading ? 'hidden' : 'visible') 
}, [isLoading]);

您还可以尝试使用requestAnimationFrame函数而不是上下文:

useEffect(() => { 
  window.requestAnimationFrame(() => {
      document.body.style.overflowY = loading ? 'hidden' : 'visible';
  });
}, [isLoading]);

好的,所以这是我想到的不是那么dirty 解决方案。而不是实施幼稚的解决方案,即。有条件的钩子:

const Layout = () => {
  const [loading, setLoading] = useState()
  if(typeof window !== 'undefined')
    useLayoutEffect(() => {
      document.body.style.overflowY = loading ? 'hidden' : 'visible'
    }, [loading])
  return ( ... )
}
export default Layout

在许多情况下,哪种感觉很脏,反图案,语义上的错误和无用(为什么要在每个渲染下检查window?),我只是将条件放在组件外面:

const LayoutView = ({ loading, setLoading }) => ( ... )
const Layout = (typeof window === 'undefined') ? (
  () => {
    const [loading, setLoading] = useState()
    return <LayoutView loading={loading} setLoading={setLoading}/>
  }
): (
  () => {
    const [loading, setLoading] = useState()
    useLayoutEffect(() => {
      document.body.style.overflowY = loading ? 'hidden' : 'visible'
    }, [loading])
    return <LayoutView loading={loading} setLoading={setLoading}/>
  }
)
export default Layout

请注意,这仅是因为我的布局效应不会影响DOM的React的一部分,这是警告的全部。

相关内容

  • 没有找到相关文章

最新更新