30秒学会 React 片段 · 2017年7月28日

30秒学会 React 片段 – useSSR

A hook that checks if the code is running on the browser or the server.

  • Create a custom hook that returns an appropriate object.
  • Use typeof window, window.document and window.document.createElement to check if the code is running on the browser.
  • Use the React.useState() hook to define the inBrowser state variable.
  • Use the React.useEffect() hook to update the inBrowser state variable and clean up at the end.
  • Use the React.useMemo() to memoize the return values of the custom hook.

代码实现

const isDOMavailable = !!(
  typeof window !== 'undefined' &&
  window.document &&
  window.document.createElement
);

const useSSR = (callback, delay) => {
  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 ? 'Running on browser' : 'Running on server' }</p>;
};

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