如何在 React 中检测屏幕尺寸是不是已更改为移动设备?
Posted
技术标签:
【中文标题】如何在 React 中检测屏幕尺寸是不是已更改为移动设备?【英文标题】:How to detect if screen size has changed to mobile in React?如何在 React 中检测屏幕尺寸是否已更改为移动设备? 【发布时间】:2017-11-12 18:51:18 【问题描述】:我正在使用 React 开发一个 Web 应用程序,需要检测屏幕尺寸何时进入移动断点以更改状态。
具体来说,当用户进入移动模式时,我需要折叠我的 sidenav,并通过存储在组件内的状态中的布尔值进行控制。
【问题讨论】:
【参考方案1】:我所做的是在组件挂载后添加一个事件监听器:
componentDidMount()
window.addEventListener("resize", this.resize.bind(this));
this.resize();
resize()
this.setState(hideNav: window.innerWidth <= 760);
componentWillUnmount()
window.removeEventListener("resize", this.resize.bind(this));
编辑: 为了保存状态更新,我稍微改变了“resize”,只在窗口宽度发生变化时才更新。
resize()
let currentHideNav = (window.innerWidth <= 760);
if (currentHideNav !== this.state.hideNav)
this.setState(hideNav: currentHideNav);
更新:是时候使用钩子了!
如果您的组件是功能性的,并且您使用挂钩 - 那么您可以使用来自 react-responsive
包的 useMediaQuery
挂钩。
import useMediaQuery from 'react-responsive';
...
const isMobile = useMediaQuery( query: `(max-width: 760px)` );
使用此钩子后,“isMobile”将在屏幕调整大小时更新,并重新渲染组件。好多了!
【讨论】:
您需要去抖动或限制该事件侦听器。您将找到here 的示例。【参考方案2】:这与@Ben Cohen answer 相同,但在将您的函数附加到 eventListner 后,还要在 componentWillUnmount
上将其删除constructor()
super();
this.state = screenWidth: null ;
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
componentDidMount()
window.addEventListener("resize", this.updateWindowDimensions());
componentWillUnmount()
window.removeEventListener("resize", this.updateWindowDimensions)
updateWindowDimensions()
this.setState( screenWidth: window.innerWidth );
【讨论】:
这是正确答案,应该这样标记。 (它也应该被去抖动或节流,正如 ivarni 对上述答案的评论。) 在调用 addEventListener 时,它应该只传递 this.updateWindowDimensions 引用而不是调用它。【参考方案3】:在 React(16.8.0+) 中使用 hooks 指的是: https://***.com/a/36862446/1075499
import useState, useEffect from 'react';
function getWindowDimensions()
const innerWidth: width, innerHeight: height = window;
return
width,
height
;
export default function useWindowDimensions()
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() =>
function handleResize()
setWindowDimensions(getWindowDimensions());
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
, []);
return windowDimensions;
【讨论】:
这是另一个答案的复制粘贴:***.com/a/36862446/1075499 不属于自己的解决方案请参考参考【参考方案4】:const [isMobile, setIsMobile] = useState(false)
//choose the screen size
const handleResize = () =>
if (window.innerWidth < 720)
setIsMobile(true)
else
setIsMobile(false)
// create an event listener
useEffect(() =>
window.addEventListener("resize", handleResize)
)
// finally you can render components conditionally if isMobile is True or False
【讨论】:
【参考方案5】:嘿,我刚刚为这个问题发布了一个 npm 包。 看看https://www.npmjs.com/package/react-getscreen
import React, Component from 'react';
import withGetScreen from 'react-getscreen'
class Test extends Component
render()
if (this.props.isMobile()) return <div>Mobile</div>;
if (this.props.isTablet()) return <div>Tablet</div>;
return <div>Desktop</div>;
export default withGetScreen(Test);
//or you may set your own breakpoints by providing an options object
const options = mobileLimit: 500, tabletLimit: 800
export default withGetScreen(Test, options);
【讨论】:
如果你问我,浏览器应该更容易获得物理屏幕尺寸而不仅仅是分辨率,因为像素密度变化很大...... 根据我的经验,根据屏幕尺寸布置的组件的可重用性较低,因为例如,如果您将它们放在 2 x 2 网格中,它们将呈现为整个屏幕而不是四分之一。 嗯,像这样的插件,只能用在容器组件之类的东西上 是的,他们适合这种情况 在func组件中如何使用?【参考方案6】:有多种存档方式,第一种方式是使用 CSS 使用此类
@media screen and (max-width: 576px)
此标签内的任何类只有在屏幕等于或小于 576px 时才可见
第二种方式是使用事件监听器
类似的东西
constructor(props)
super(props);
this.state =
isToggle: null
this.resizeScreen = this.resizeScreen.bind(this);
componentDidMount()
window.addEventListener("resize", this.resizeScreen());
resizeScreen()
if(window.innerWidth === 576)
this.setState(isToggle:'I was resized');
即使使用事件监听器,我仍然更喜欢 CSS 方式,因为我们可以使用多种屏幕尺寸而无需进一步的 js 编码。
我希望这会有所帮助!
【讨论】:
【参考方案7】:react-screentype-hook 库允许您开箱即用地执行此操作。 https://www.npmjs.com/package/react-screentype-hook
您可以使用它提供的默认断点,如下所示
const screenType = useScreenType();
screenType 具有以下形状
isLargeDesktop: Boolean,
isDesktop: Boolean,
isMobile: Boolean,
isTablet: Boolean
或者你甚至可以像这样配置你的自定义断点
const screenType = useScreenType(
mobile: 400,
tablet: 800,
desktop: 1000,
largeDesktop: 1600
);
【讨论】:
【参考方案8】:在Functional Component中,我们可以通过useTheme和useMediaQuery来检测屏幕大小。 常量主题 = useTheme(); const xs = useMediaQuery(theme.breakpoints.only('xs')); const sm = useMediaQuery(theme.breakpoints.only('sm')); const md = useMediaQuery(theme.breakpoints.only('md')); const lg = useMediaQuery(theme.breakpoints.only('lg')); const xl = useMediaQuery(theme.breakpoints.only('xl'));
【讨论】:
以上是关于如何在 React 中检测屏幕尺寸是不是已更改为移动设备?的主要内容,如果未能解决你的问题,请参考以下文章
所有警报对话框消息和textField都已更改为单行。请检查图像