mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-04 09:19:16 +02:00
fix(theme): fix useWindowSize React hydration issue (#9446)
This commit is contained in:
parent
d07567e411
commit
8d19054d91
1 changed files with 10 additions and 16 deletions
|
@ -21,15 +21,15 @@ const DesktopThresholdWidth = 996;
|
|||
|
||||
function getWindowSize() {
|
||||
if (!ExecutionEnvironment.canUseDOM) {
|
||||
return windowSizes.ssr;
|
||||
throw new Error(
|
||||
'getWindowSize() should only be called after React hydration',
|
||||
);
|
||||
}
|
||||
return window.innerWidth > DesktopThresholdWidth
|
||||
? windowSizes.desktop
|
||||
: windowSizes.mobile;
|
||||
}
|
||||
|
||||
const DevSimulateSSR = process.env.NODE_ENV === 'development' && true;
|
||||
|
||||
/**
|
||||
* Gets the current window size as an enum value. We don't want it to return the
|
||||
* actual width value, so that it only re-renders once a breakpoint is crossed.
|
||||
|
@ -39,32 +39,26 @@ const DevSimulateSSR = process.env.NODE_ENV === 'development' && true;
|
|||
* may need to render BOTH the mobile/desktop elements (and hide one of them
|
||||
* with mediaquery). We don't return `undefined` on purpose, to make it more
|
||||
* explicit.
|
||||
*
|
||||
* In development mode, this hook will still return `"ssr"` for one second, to
|
||||
* catch potential layout shifts, similar to strict mode calling effects twice.
|
||||
*/
|
||||
export function useWindowSize(): WindowSize {
|
||||
const [windowSize, setWindowSize] = useState<WindowSize>(() => {
|
||||
if (DevSimulateSSR) {
|
||||
return 'ssr';
|
||||
}
|
||||
return getWindowSize();
|
||||
});
|
||||
const [windowSize, setWindowSize] = useState<WindowSize>(
|
||||
() =>
|
||||
// super important to return a constant value to avoid hydration mismatch
|
||||
// see https://github.com/facebook/docusaurus/issues/9379
|
||||
'ssr',
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
function updateWindowSize() {
|
||||
setWindowSize(getWindowSize());
|
||||
}
|
||||
|
||||
const timeout = DevSimulateSSR
|
||||
? window.setTimeout(updateWindowSize, 1000)
|
||||
: undefined;
|
||||
updateWindowSize();
|
||||
|
||||
window.addEventListener('resize', updateWindowSize);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('resize', updateWindowSize);
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue