简体   繁体   English

react-responsive 不适用于服务器端渲染

[英]react-responsive doesn't work with Server-side rendering

I am trying to use react-responsive to conditional rendering components base on device width.我正在尝试根据设备宽度使用对条件渲染组件的反应响应。 Everything worked great in client side, but for SSR I followed the documentation to use Context to pass a specific width for initial server render.在客户端一切都很好,但对于 SSR,我按照文档使用 Context 为初始服务器渲染传递特定宽度。 However, the width that react-responsive received now hard set to the width in Context even if I resize the browser.但是,即使我调整浏览器的大小,react-responsive 收到的宽度现在也很难设置为 Context 中的宽度。

Component to define device base on device width:根据设备宽度定义设备的组件:

import { useMediaQuery } from 'react-responsive';

export const Desktop = ({ children }) => {
const isDesktop = useMediaQuery({ minWidth: 801 });
return isDesktop ? children : null;
};

export const Tablet = ({ children }) => {
const isTablet = useMediaQuery({ minWidth: 426, maxWidth: 800 });
return isTablet ? children : null;
};

export const Mobile = ({ children }) => {
const isMobile = useMediaQuery({ maxWidth: 425 });
return isMobile ? children : null;
};

export const MobileTablet = ({ children }) => {
const isMobile = useMediaQuery({ maxWidth: 800 });
return isMobile ? children : null;
};

My use for DeviceIdentifier component:我对 DeviceIdentifier 组件的使用:

...
     <Desktop>
        <CategoryTree />
     </Desktop>

...

      <MobileTablet>
        <BurgerMenu
          open={burgerMenuOpen}
          onOpenStateChange={setBurgerMenuOpen}
        />
      </MobileTablet>
...

Context wrapper in _app.js _app.js 中的上下文包装器

import { Context as ResponsiveContext } from 'react-responsive';
...
<ResponsiveContext.Provider value={{ width: 1440 }}>
    <Component {...pageProps} />
</ResponsiveContext.Provider>
...

Since I set the width in the context 1440px, my BurgerMenu component is currently never rendered.由于我将上下文中的宽度设置为 1440 像素,因此我的 BurgerMenu 组件当前从未呈现。 Anybody have any idea how to make this react-responsive library work in SRR?有人知道如何让这个反应响应库在 SRR 中工作吗?

Could you check for a window object and use that width and hardcode 1440 for server side:您能否检查window object 并将该宽度和硬编码1440用于服务器端:

import { Context as ResponsiveContext } from 'react-responsive';
...
<ResponsiveContext.Provider value={{ width: window.innerWidth || 1440 }}>
    <Component {...pageProps} />
</ResponsiveContext.Provider>
...

From reactjs docs To fix this, either move that logic to useEffect (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until useLayoutEffect runs).来自 reactjs 文档要解决此问题,请将该逻辑移至 useEffect(如果第一次渲染不需要它),或者延迟显示该组件直到客户端渲染之后(如果 HTML 在 useLayoutEffect 运行之前看起来已损坏)。

To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with showChild && and defer showing it with useEffect(() => { setShowChild(true); }, []).要从服务器渲染的 HTML 中排除需要布局效果的组件,请使用 showChild && 有条件地渲染它,并使用 useEffect(() => { setShowChild(true); }, []) 延迟显示它。 This way, the UI doesn't appear broken before hydration.这样,用户界面在水合之前不会出现损坏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM