// imports
const PageComponent = () => {
const resizeTimoutRef = useRef(null)
const [screenSizeState, setScreenSizeState] = useState(null) // initialized at null because on the server you don't have the DOM
// basic function to get the breakpoint as a string based on the width of the window
const getScreenSize = windowWidth =>
windowWidth < 768
? "sm"
windowWidth < 1024
? "md"
: windowWidth < 1280
? "lg"
: "xl"
useEffect(() => {
// here i set the current screen breakpoint immediately on the page load
setScreenSizeState(getScreenSize(window.innerWidth))
// here i add a listener for the resize event of the window
window.addEventListener('resize', () => {
// if a resize timout exists i clear it to prevent calling setState too many times
if(resizeTimeoutRef.current) clearTimeout(resizeTimeoutRef.current)
// here i set the timeout ref to the function that will be executed 150ms after the last resize event, again, to prevent calling setState too many times
resizeTimeoutRef.current = setTimeout(() => setScreenSizeState(getScreenSize(window.innerWidth)), 150)
})
}, []) // empty array means that this hook will be called only once on the first page load
return (
<>
<div style={{ display: screenSizeState === 'sm' ? 'block' : 'none' }}>
Always present in the DOM but displayed only on 'sm' breakpoint
</div>
<div style={{ display: ['md', 'lg'].includes(screenSizeState) ? 'block' : 'none' }}>
Always present in the DOM but displayed only on 'md' and 'lg' breakpoints
</div>
</>
)
}
export default PageComponent
2条答案
按热度按时间qnzebej01#
好的,如果我理解了你的问题,你试图呈现一个页面,其中包含所有与设备相关的组件,但只显示(使用css)当前设备的组件。
我的方法是:
在页面组件中:
当然,您可以将此代码修改为自定义钩子,使其可重用,只需执行以下操作:
这样您就可以在页面组件中使用它,如下所示:
ztyzrc3y2#
由于NextJs是服务器端呈现的,因此服务器无法知道它将生成的html发送到什么屏幕大小。
现在'useEffect'来拯救,因为useEffect只在客户端运行。
一旦页面加载到浏览器上,我们就可以使用它来获取屏幕大小类型。
您可以按以下方式使用“react-device-detect”。
那你回来的时候
在app.js文件中使用此方法一次,并将其作为props传递给layout,而不是在每个组件中使用useeffect。