在React中进行条件渲染时,未正确应用CSS样式

在React中进行条件渲染时,未正确应用CSS样式,css,reactjs,next.js,Css,Reactjs,Next.js,我需要根据屏幕大小有条件地渲染组件 我使用nextjs和getInitialProps获取数据,页面是服务器端呈现的。我想在客户端检测设备屏幕大小,所以我实现了一个定制的钩子 UseWindowsSize.js 从'react'导入{useffect,useState}; 导出默认函数useWindowsSize(){ 常量[WindowsSize,SetWindowsSize]=useState({ 宽度:typeof window==“未定义”?1200:window.innerWidth,

我需要根据屏幕大小有条件地渲染组件

我使用nextjs和getInitialProps获取数据,页面是服务器端呈现的。我想在客户端检测设备屏幕大小,所以我实现了一个定制的钩子

UseWindowsSize.js

从'react'导入{useffect,useState};
导出默认函数useWindowsSize(){
常量[WindowsSize,SetWindowsSize]=useState({
宽度:typeof window==“未定义”?1200:window.innerWidth,//默认宽度1200
});
useffect(()=>{
//调用窗口调整大小的处理程序
函数handleResize(){
//将窗口宽度/高度设置为状态
设置窗口大小({
宽度:window.innerWidth,
//高度:window.innerHeight,
});
}
//添加事件侦听器
window.addEventListener('resize',handleResize);
//立即调用处理程序,以便使用初始窗口大小更新状态
handleResize();
//清除时删除事件侦听器
return()=>window.removeEventListener('resize',handleResize);
},[]);//空数组确保仅在装载时运行效果

return windowSize.width这是一个与React如何从SSR修补DOM相关的问题。当客户端和服务器端呈现不匹配时,React将仅修补/同步节点的文本上下文。DOM属性不会自动更新。在您的情况下,SSR结果具有桌面样式,因为没有
窗口
对象,客户端有移动结果。不匹配后,React将文本节点从“桌面”更新为
移动
,但不更新样式属性

在我看来,您可以使用两种不同的方法。您可以使用媒体查询根据屏幕宽度而不是挂钩来设置组件的样式。如果您正在执行SSR,而不是SSG,则可以使用用户代理
req.headers[“user agent”]
来检测正在查看设备的设备

对于第一种方法,您可能需要渲染更多的DOM节点。对于第二种方法,您将无法知道实际的视口大小,这可能会导致视觉问题。您可以将这两种方法结合起来,为用户提供良好的查看体验

参考


谢谢@Andrew Zheng的详细解释!今天我学到了

我知道我可以通过使用纯CSS媒体查询来设计布局,但是我的用例需要一个变量,比如
isMobile
to

if(isMobile){
dosomethingonloyonmobileWeb();
}否则{
doSomethingOnlyForDesktopWeb();
}
因此,我结合了您提供的两种方法,并以这种方式修改了我的挂钩:

导出默认函数UseWindowsSize(userAgent){
设isMobile=Boolean(
用户代理&&
userAgent.match(
/Android |黑莓| iPhone | iPod | Opera Mini | IEMobile | WPDesktop/i
)
);
常量[WindowsSize,SetWindowsSize]=useState({
宽度:isServer
?isMobile
?断点_小
:断点\大
:window.innerWidth,
});
useffect(()=>{
//调用窗口调整大小的处理程序
函数handleResize(){
//将窗口宽度/高度设置为状态
设置窗口大小({
宽度:window.innerWidth,
//高度:window.innerHeight,
});
}
//添加事件侦听器
window.addEventListener('resize',handleResize);
//立即调用处理程序,以便使用初始窗口大小更新状态
handleResize();
//清除时删除事件侦听器
return()=>window.removeEventListener('resize',handleResize);
},[]);//空数组确保仅在装载时运行效果

返回windowSize.width我很高兴你找到了答案!