Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在不了解设备的情况下对响应性应用程序进行SSR';屏幕大小是多少?_Reactjs_Responsive Design_Media Queries_Server Side Rendering_Styled Components - Fatal编程技术网

Reactjs 如何在不了解设备的情况下对响应性应用程序进行SSR';屏幕大小是多少?

Reactjs 如何在不了解设备的情况下对响应性应用程序进行SSR';屏幕大小是多少?,reactjs,responsive-design,media-queries,server-side-rendering,styled-components,Reactjs,Responsive Design,Media Queries,Server Side Rendering,Styled Components,我想为我的用户SSR我的应用程序 但是我的应用程序代码使用useffect来检测用户屏幕宽度的大小,然后才呈现应用程序 比如: App.js // THE LAYOUT INITIAL STATE IS NULL useEffect(() => { // CHECK FOR window.innerWidth AND DECIDE LAYOUT // UPDATE LAYOUT STATE }); return( layout &&

我想为我的用户SSR我的应用程序

但是我的应用程序代码使用
useffect
来检测用户屏幕宽度的大小,然后才呈现应用程序

比如:

App.js

  // THE LAYOUT INITIAL STATE IS NULL

  useEffect(() => {
    // CHECK FOR window.innerWidth AND DECIDE LAYOUT
    // UPDATE LAYOUT STATE
  });

  return(
    layout && <AppComponents>   // IF THERE IS NO LAYOUT, NOTHING IS RENDERED
  );
 // I SERVE THE LAYOUT THROUGH CONTEXT AND I ACCESS IT INSIDE OF THE COMPONENTS

 const layout = useLayout();

 return(
   layout === "MOBILE" ? ComponentMobile : ComponentDesktop
 );
问题

我不能依靠
useffect
中的代码在服务器上渲染内容。因此,不知何故,我需要“决定”在服务器上第一次也是唯一一次渲染使用哪种布局

因此,我的选择,至少到目前为止我想到的是:

选项#1

尝试猜测用户的设备屏幕大小,并呈现可能不适合其屏幕大小的内容

因为现在,我呈现的CSS样式取决于用户的屏幕大小

选项2

完全移动到媒体查询以处理响应性,因此CSS将始终保持不变,并将自动适应所使用的屏幕大小

到目前为止,我根本没有使用媒体查询。所有我的布局决策都是在渲染过程中做出的,所有组件都根据从App.js状态决定的布局来渲染样式


最好的处理方法是什么?这方面有最佳实践吗

注意:

我使用的是
样式化组件
,所以我基本上就是这样做的:

这是一个粗略的例子,但这就是想法


// THIS IS MUCH EASIER TO WRITE THAN A BUNCH OF MEDIA QUERIES (IMO)

const Styled_DIV = styled.div`
  font-size: ${props => 
    props.layout === "MOBILE" ? "16px" 
    : props.layout === "TABLET" ? "18px" 
    : "20px"
  };
`;

很好,您已经在使用
样式化组件了
。添加媒体查询现在比您建议的方法更简单、更直接(IMO)

一般来说,使用CSS配置布局比使用JS性能更好。而对于SSR,就像你说的,服务器还不能用JS和
useffect
确定屏幕大小

如果您首先是移动用户,您可以使用如下媒体查询编写上述逻辑:

const Styled\u DIV=Styled.DIV`
字体大小:16px;
@介质(最小宽度:768px){
字号:18px;
}
@介质(最小宽度:1024px){
字体大小:20px;
}
`
我编写了一个助手对象导出,因此我不必记住像素大小,甚至不必记住媒体查询的语法:

导出常量大小={
片剂:768,
桌面:1024,
}
导出常量设备={
平板电脑:`@media(最小宽度:${size.tablet}px)`,
桌面:`@media(最小宽度:${size.desktop}px)`,
}
所以现在我只需要写:

const Styled\u DIV=Styled.DIV`
字体大小:16px;
${device.tablet}{
字号:18px;
}
${device.desktop}{
字体大小:20px;
}
`

由于
device
是一个导出的对象,因此当我开始键入时,我的VSCode编辑器会自动帮助我导入它。

似乎不是一个简单的解决方案。根据布局的不同,媒体查询可能是首选。在我们的项目中,这是乏味的,但可能更可靠。如果布局完全不同,那么检测设备大小并提供不同版本的应用程序可能是有意义的?我还没有完全解决这个问题,因为我只是为机器人爬虫做SSR,我有可能预先知道这些爬虫的移动设备。例如,使用Nexus 5x。所以我是基于这个渲染的。对于用户来说,我只会尝试媒体查询。但是,如果您正在客户端上水合,可能首先显示加载程序,水合JS并获得屏幕宽度,然后才渲染页面的其余部分。你觉得呢?是的,如果SSR只适用于标准的登录页或加载器,那就容易多了。如果你想让整个应用程序都能使用SSR,比如深度链接的子页面,这就变得很棘手了。可能无法逃避媒体查询/其他应用程序。