我正在尝试构建一个跟踪窗口大小的React上下文对象,因此我可以基于window.innerWidth使用特定的组件,而不必在多个位置确定该值。我已经设置了以下“ DeviceContext”组件:
import React, { createContext, useState, useLayoutEffect } from "react"
import { size } from "../utilities/breakpoints"
export const DeviceContext = createContext()
const getSize = () => {
let width = window.innerWidth > 0 ? window.innerWidth : window.screen.width
if (width > size.huge) {
return "huge"
} else if (width >= size.large) {
return "large"
} else if (width >= size.med) {
return "med"
} else {
return "small"
}
}
export function DeviceProvider({ children }) {
let [size, setSize] = useState(getSize())
useLayoutEffect(() => {
function resize() {
setSize(getSize())
}
window.addEventListener("resize", resize)
return () => {
window.removeEventListener("resize", resize)
}
})
return (
<DeviceContext.Provider value={size}>{children}</DeviceContext.Provider>
)
}
然后我将Layout组件包装在<DeviceProvider>
中,并在这样的菜单组件中使用它:
export const Menu = ({ children }) => {
return (
<DeviceContext.Consumer>
{screenSize => {
if (screenSize === "huge" || screenSize === "large") {
return <div>Not done yet...</div>
} else {
return <ResponsiveNav />
}
}}
</DeviceContext.Consumer>
)
}
Menu.propTypes = {
children: PropTypes.oneOfType([
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]),
}
export default Menu
当window.innerwidth大于特定值,而<ResponsivNav/>
大于特定值时,我希望看到的是“尚未完成...”。我希望在调整窗口大小时(即通过开发工具)我的上下文会更新,但是它只是偶尔更新。如果我在resize方法中删除对“ previous”的引用,则根本不会更新。
提前感谢您的任何建议!
答案 0 :(得分:1)
通过不在您的useLayoutEffect
中提供依赖项数组,事件侦听器将在每次状态更新时被读取。在此处设置一个空数组只会将侦听器应用于安装。
useLayoutEffect(() => {
function resize() {
setSize(getSize())
}
window.addEventListener("resize", resize)
return () => {
window.removeEventListener("resize", resize)
}
}, []) // <--- empty dependency array