[英]How to set window resize event listener value to React State?
This issue is very simple but I probably overlook very little point.这个问题很简单,但我可能忽略了很少一点。 Window screen size is listening by
PostLayout
component. PostLayout
组件正在监听窗口屏幕大小。 When window width is less than 768px, I expect that isDesktopSize
is false.当窗口宽度小于 768px 时,我希望
isDesktopSize
为 false。 I tried everything like using arrow function in setIsDesktopSize
, using text inside of true or false for state value, using callback method etc... but it's not working.我尝试了所有方法,例如在
setIsDesktopSize
中使用箭头函数,在 true 或 false 中使用文本作为状态值,使用回调方法等……但它不起作用。
PostLayout
shared below: PostLayout
分享如下:
import React, {useState,useEffect, useCallback} from 'react'
import LeftSideNavbar from './LeftSideNavbar'
import TopNavbar from './TopNavbar'
export default function PostLayout({children}) {
const [isDesktopSize, setIsDesktopSize] = useState(true)
let autoResize = () => {
console.log("Desktop: " + isDesktopSize);
console.log(window.innerWidth);
if(window.innerWidth < 768 ){
setIsDesktopSize(false)
}else{
setIsDesktopSize(true)
}
}
useEffect(() => {
window.addEventListener('resize', autoResize)
autoResize();
}, [])
return (
<>
<TopNavbar isDesktopSize={isDesktopSize}/>
<main>
<LeftSideNavbar/>
{children}
</main>
</>
)
}
console log is shared below:控制台日志在下面共享:
Desktop: true
627
This could probably be extracted into a custom hook.这可能会被提取到自定义钩子中。 There's a few things you'd want to address:
您需要解决一些问题:
true
, but when the component loads, that may not be correct.true
,但是当组件加载时,这可能不正确。 This is probably why you see an incorrect console log on the first execution of the effect. Here's an example of a custom hook that addresses those:这是解决这些问题的自定义钩子的示例:
function testIsDesktop() {
if (typeof window === 'undefined') {
return true;
}
return window.innerWidth >= 768;
}
function useIsDesktopSize() {
// Initialize the desktop size to an accurate value on initial state set
const [isDesktopSize, setIsDesktopSize] = useState(testIsDesktop);
useEffect(() => {
if (typeof window === 'undefined') {
return;
}
function autoResize() {
setIsDesktopSize(testIsDesktop());
}
window.addEventListener('resize', autoResize);
// This is likely unnecessary, as the initial state should capture
// the size, however if a resize occurs between initial state set by
// React and before the event listener is attached, this
// will just make sure it captures that.
autoResize();
// Return a function to disconnect the event listener
return () => window.removeEventListener('resize', autoResize);
}, [])
return isDesktopSize;
}
Then to use this, your other component would look like this (assuming your custom hook is just in this same file -- though it may be useful to extract it to a separate file and import it):然后要使用它,您的其他组件将如下所示(假设您的自定义挂钩只是在同一个文件中 - 尽管将其提取到单独的文件并导入它可能很有用):
import React, { useState } from 'react'
import LeftSideNavbar from './LeftSideNavbar'
import TopNavbar from './TopNavbar'
export default function PostLayout({children}) {
const isDesktopSize = useIsDesktopSize();
return (
<>
<TopNavbar isDesktopSize={isDesktopSize}/>
<main>
<LeftSideNavbar/>
{children}
</main>
</>
)
}
EDIT: I modified this slightly so it should theoretically work with a server-side renderer, which will assume a desktop size.编辑:我对此稍作修改,因此理论上它应该与服务器端渲染器一起使用,该渲染器将假定桌面大小。
Try this, you are setting isDesktopSizze to 'mobile', which is === true试试这个,你将 isDesktopSizze 设置为'mobile',即 === true
const [isDesktopSize, setIsDesktopSize] = useState(true) let autoResize = () => { console.log("Desktop: " + isDesktopSize); console.log(window.innerWidth); if(window.innerWidth < 768 ){ setIsDesktopSize(true) }else{ setIsDesktopSize(false) } }
I didn't find such a package on npm and I thought it would be nice to create one: https://www.npmjs.com/package/use-device-detect .我在 npm 上没有找到这样的包,我认为创建一个会很好: https ://www.npmjs.com/package/use-device-detect。 I think it will help someone :)
我认为它会帮助某人:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.