javascript - 当代码需要设备宽度时,ReactDOMServer 的行为如何?
问题描述
我有以下钩子,用于在整个应用程序中构建响应式组件。
我正在研究实现服务器端渲染。
使用WindowWidth.js
import {useEffect, useRef, useState} from 'react';
function useWindowWidth() {
const hasResized = useRef(false);
const [windowSize,setWindowSize] = useState(window.innerWidth);
useEffect(() => {
function handleResize() {
if (hasResized.current === true) {
return;
}
hasResized.current = true;
throtled_forceUpdate();
}
function throtled_forceUpdate() {
setTimeout(()=>{
// console.log('I will be updated!');
// console.log(window.innerWidth);
setWindowSize(window.innerWidth);
hasResized.current = false;
},250);
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowSize;
}
export default useWindowWidth;
应用程序.js
import React from 'react';
import useWindowWidth from './hooks/useWindowWidth';
function App(props) {
const windowWidth = useWindowWidth();
return(
windowWidth > 1200 ?
<DesktopLayout/>
: <MobileLayout/>
);
}
ReactDOMServer
ReactDOMServer.renderToString(App);
当 ReactDOMServer 遇到这样的事情时,它的行为是什么?这种情况的解决方法是什么?
解决方案
无法在服务器端获取窗口宽度。一种解决方法是使用传入请求中的用户代理来确定应该在服务器上呈现哪个组件。
const deviceType = useDeviceType();
return deviceType === 'mobile' ? <MobileLayout /> : <DesktopLayout />;
或者正如文档提到的:
如果您有意在服务器和客户端上渲染不同的东西,您可以进行两次渲染。在客户端呈现不同内容的组件可以读取像 this.state.isClient 这样的状态变量,您可以在 componentDidMount() 中将其设置为 true。这样,初始渲染通道将渲染与服务器相同的内容,避免不匹配,但额外的通道将在水化后立即同步发生。请注意,这种方法会使您的组件变慢,因为它们必须渲染两次,因此请谨慎使用。
推荐阅读
- java - 保护 Spring Boot 2 Actuator Prometheus 端点
- apache-nifi - Jolt json 转换问题。有一个记录,里面有一个数组,需要转换成一个记录数组
- c# - 如何在 C# 中使用特殊语言创建文件名?
- visual-studio-code - linux mint 上的 Vscode 多行编辑/选择
- c - 使用哈希表对 ascii 代码中的所有字母进行简单加密
- c++ - decltype(1, t) 应该是左值引用吗?(编译器不同意)
- r - 数据框中列的奇数类型
- linux - 不支持 TCP_USER_TIMEOUT 套接字选项
- amazon-web-services - 如何从 AMQ 迁移到 SQS
- python - 有条件的取值