我目前使用'react-responsive'来切换打开或关闭某些组件,这取决于应用程序是在桌面还是移动设备上查看。
简化的例子:
import { useMediaQuery } from 'react-responsive'
export default function MyComponent(props) {
const isMobile = useMediaQuery({ query: `(max-width: 480px)` })
return (
<Wrapper>
{ isMobile ? <ComponentMobile /> : <ComponentDesktop /> }
</Wrapper>
)
}
当我在应用程序中从一个页面导航到另一个页面时,这是完美的,但是当我第一次打开网站时,组件都是错误的(仍然渲染ComponentDesktop),即使我在移动设备上。
我的猜测是组件正在服务器端渲染,当它涉及到前端时,它不会更新。
正确的方法是什么?
多谢!
最近遇到了一个类似的问题,最终使用CSS显示或隐藏组件。Material UI有一个Hidden组件,允许你使用CSS轻松地做到这一点,但肯定还有其他解决方案。
查看Vercel的视频,了解多种可能的实现:https://www.youtube.com/watch?v=K7g8X_VRDy8
检查用户代理也是可能的,但我个人喜欢CSS的想法只是因为它根据屏幕的宽度自动显示或隐藏组件,但它肯定不是完美的。
根据reactjs文档为了解决这个问题,要么,逻辑转移到useEffect第一渲染(如果它不是必要的),或延迟显示组件,直到客户端显示(如果HTML看起来破碎,直到useLayoutEffect运行)。
要从服务器端呈现的HTML中排除需要布局效果的组件,可以使用showChild &&并使用useEffect(() =>{setShowChild(真正的);},[])。这样,UI在水化之前就不会出现破损。
我不得不在useMediaQuery()
钩子周围创建一个useEffect()
包装器来解决水合作用问题…
import { useEffect, useState } from 'react';
import { useMediaQuery } from 'react-responsive';
export const IS_SERVER = typeof window === 'undefined';
export const MOBILE_SCREEN_MAX_WIDTH = 640;
export const SERVER_SIDE_IS_MOBILE_VALUE = true; // true - for mobile, false - for desktop
/**
* Hook to detect onMobile vs. onDesktop using Media Query
* @returns {boolean} true when on onMobile, false when on onDesktop
*/
function useOnMobileByMediaQuery() {
const onMobile = useMediaQuery({ maxWidth: MOBILE_SCREEN_MAX_WIDTH });
return onMobile;
}
/**
* Hook to detect onMobile vs. onDesktop with Next.js workaround
* @returns {boolean} true when on onMobile, false when on onDesktop
*/
function useOnMobileForNextJs() {
const onMobile = useOnMobileByMediaQuery();
const [onMobileDelayed, setOnMobileDelayed] = useState(SERVER_SIDE_IS_MOBILE_VALUE);
useEffect(() => {
setOnMobileDelayed(onMobile); // Next.js don't allow to use useOnMobileXxx() directly, so we need to use this workaround
}, [onMobile]);
return onMobileDelayed;
}
/**
* We need a "smart export wrappers", because we can not use hooks on the server side
*/
export const useOnMobile = IS_SERVER ? () => SERVER_SIDE_IS_MOBILE_VALUE : useOnMobileForNextJs;
公共要点在这里https://gist.github.com/karpolan/9b9b2c781480cfc9a4bd2bfe62f332f3