在React项目使用服务端渲染,如果使用了 useLayoutEffect 时,会有警告:

⚠️ 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 the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-ssr for common fixes.

解决方法

使用useEffect替代

如果副作用对首次渲染不重要,那么可以直接使用 useEffectuseEffectuseLayoutEffect 如何选择,可以查看React的useEffect和useLayoutEffect的区别

MyComponent() {
  useEffect(() => {
    // ...
  });
}

useLayoutEffect 一样,它不会在服务器上运行,但也不会发出警告。    

使用 useLayoutEffect 延迟显示组件

如果在首次渲染时使用 useEffect 发现UI出现了问题,必须要切换到 useLayoutEffect 正常。那么可以推迟组件的显示,直到客户端的 JavaScript 完成加载并激活了该组件。在服务器渲染的 HTML 中不包含那些需要布局效果的子组件。

function Parent() {
  const [showChild, setShowChild] = useState(false);
  
  useEffect(() => {
    // 组件在客户端挂载后,再显示需要用到 useLayoutEffect 的组件。
    setShowChild(true);
  }, []);
  
  if (!showChild) {
    return null;
  }

  return <Child {...props} />;
}

function Child(props) {
  useLayoutEffect(() => {
    // 执行 useLayoutEffect 逻辑
  });
}