React useSSR钩子

检查代码是在浏览器还是服务器上运行。

  • 创建一个自定义钩子,返回一个适当的对象。
  • 使用typeofWindowWindow.documentDocument.createElement()来检查代码是否在浏览器上运行。
  • 使用useState()钩子来定义inBrowser状态变量。
  • 使用useEffect()钩子来更新inBrowser状态变量,并在结束时进行清理。
  • 使用useMemo()钩子来记忆自定义钩子的返回值。
const isDOMavailable = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
);

const useSSR = () => {
  const [inBrowser, setInBrowser] = React.useState(isDOMavailable);

  React.useEffect(() => {
    setInBrowser(isDOMavailable);
    return () => {
      setInBrowser(false);
    };
  }, []);

  const useSSRObject = React.useMemo(
    () => ({
      isBrowser: inBrowser,
      isServer: !inBrowser,
      canUseWorkers: typeof Worker !== 'undefined',
      canUseEventListeners: inBrowser && !!window.addEventListener,
      canUseViewport: inBrowser && !!window.screen
    }),
    [inBrowser]
  );

  return React.useMemo(
    () => Object.assign(Object.values(useSSRObject), useSSRObject),
    [inBrowser]
  );
};

const SSRChecker = props => {
  let { isBrowser, isServer } = useSSR();

  return <p>{isBrowser ? '在浏览器上运行' : '在服务器上运行'}</p>;
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <SSRChecker />
);

ReactDOM.createRoot(document.getElementById('root')).render( ); ```