docs/guide/blog/ssr.en-US.md
Server-Side Rendering refers to the page processing technology where the HTML structure of the page is spliced on the server side. Generally used to solve SEO problems and speed up the first screen.
Since SSR executes JS code in a non-browser environment, there will be many problems. This article mainly introduces the common problems and solutions of React Hooks in SSR mode.
SSR is to run React code in a node environment, while global properties such as window, document, and navigator are not available at this time. If you use these properties directly, you will get errors like window is not defined, document is not defined, navigator is not defined, etc.
A common misuse is that global properties, such as document, are used directly during the execution of Hooks.
import React, { useState } from 'react';
export default () => {
const [state, setState] = useState(document.visibilityState);
return state;
};
import React, { useState, useEffect } from 'react';
export default () => {
const [state, setState] = useState();
useEffect(() => {
setState(document.visibilityState);
}, []);
return state;
};
isBrowserimport React, { useState } from 'react';
function isBrowser() {
return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
}
export default () => {
const [state, setState] = useState(isBrowser() && document.visibilityState);
return state;
};
If useLayoutEffect is used, the following warning will appear in SSR mode
⚠️ 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.
import { useLayoutEffect, useEffect } from 'react';
const useIsomorphicLayoutEffect = isBrowser() ? useLayoutEffect : useEffect;
export default useIsomorphicLayoutEffect;
isBrowser to determine whether to execute in the browser environmentimport React, { useState } from 'react';
import { useEventListener } from 'ahooks';
export default () => {
const [value, setValue] = useState(0);
const clickHandler = () => {
setValue(value + 1);
};
useEventListener(
'click',
clickHandler,
{
- target: document.getElementById('click-btn')
+ target: () => document.getElementById('click-btn')
}
);
return (
<button id="click-btn" type="button">
You click {value} times
</button>
);
};
useIsomorphicLayoutEffect instead of useLayoutEffect