这个问题很简单,但我可能忽略了很少一点。窗口屏幕大小由 PostLayout
组件监听。当窗口宽度小于 768px 时,我预计 isDesktopSize
为 false。我尝试了所有方法,例如在 setIsDesktopSize
中使用箭头函数、使用 true 或 false 中的文本作为状态值、使用回调方法等...但它不起作用。
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>
</>
)
}
控制台日志分享如下:
Desktop: true
627
最佳答案
这可能会被提取到自定义 Hook 中。您需要解决一些问题:
- 现在您将状态默认为
true
,但是当组件加载时,这可能不正确。这可能就是您在第一次执行 effect 时看到不正确的控制台日志的原因。准确计算初始状态可以避免出现卡顿/双重渲染。 - 您没有在卸载组件时断开调整大小监听器,这可能会导致在卸载后尝试在组件上设置状态时出错。
这是解决这些问题的自定义 Hook 示例:
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;
}
然后要使用它,您的其他组件将如下所示(假设您的自定义 Hook 就在同一个文件中——尽管将它提取到一个单独的文件并导入它可能很有用):
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>
</>
)
}
编辑:我对此稍作修改,因此理论上它应该可以与服务器端渲染器一起使用,该渲染器将采用桌面大小。
关于reactjs - 如何将窗口调整大小事件监听器值设置为 react 状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68019102/