服务端渲染(Server-SideRendering)是指由服务端完成页面HTML结构拼接的页面处理技术。一般用于解决SEO问题和首屏加载速度问题。由于SSR是在非浏览器环境下执行JS代码,所以会出现很多问题。本文主要介绍SSR模式下ReactHooks的常见问题及解决方法。关于SSR的更多介绍,请参考UmiJS文档《服务端渲染(SSR)[1]》。问题1:缺少DOM/BOM。SSR是在node环境下运行React代码,但是此时window、document、navigator等全局属性是不可用的。如果直接使用这些属性,会报windowisnotdefined、documentisnotdefined、navigatorisnotdefined等错误。一个常见的错误是在执行Hooks时直接使用全局属性,例如document。importReact,{useState}from'react';exportdefault()=>{const[state,setState]=useState(document.visibilityState);returnstate;}解决方法1.将访问DOM/BOM的方法放在useEffect/useLayoutEffect(server不会执行),避免server执行时报错,例如:importReact,{useState,useEffect}from'react';exportdefault()=>{const[state,setState]=useState();useEffect(()=>{setState(document.visibilityState);},[]);returnstate;}2。使用isBrowser[2]判断环境const[state,setState]=useState(isBrowser()&&document.visibilityState);returnstate;}问题2useLayoutEffect警告如果使用useLayoutEffect,在SSR模式下,会出现如下警告??警告:useLayoutEffect在服务端什么都不做,因为它效果无法编码为服务器渲染器的输出格式。这将导致初始的、未水化的UI和内部不匹配找到用户界面。为避免这种情况,useLayoutEffect只应在仅在客户端呈现的组件中使用。有关常见修复,请参阅https://fb.me/react-uselayouteffect-SSR。方案使用useEffect代替useLayoutEffect(废话)根据环境动态指定是使用useEffect还是useLayoutEffect。这是社区的hack方案,目前在react-redux[3]、react-use[4]、react-beautiful-dnd[5]中使用。import{useLayoutEffect,useEffect}from'react';constuseIsomorphicLayoutEffect=isBrowser()?useLayoutEffect:useEffect;exportdefaultuseIsomorphicLayoutEffect;总结:写Hooks时注意1.不要在非useEffect/useLayoutEffect中直接使用DOM/BOM属性2.useEffect/useLayoutEffect使用DOM/BOM属性时,使用isBrowser判断是否在浏览器环境下执行。3、如果某个Hooks需要接收DOM/BOM属性,需要支持函数形式传参。以ahooks的useEventListener为例,必须支持function形式指定target属性。importReact,{useState}from'react';import{useEventListener}from'ahooks';exportdefault()=>{const[value,setValue]=useState(0);constclickHandler=()=>{setValue(value+1);};useEventListener('click',clickHandler,{-target:document.getElemenetById('click-btn')+target:()=>document.getElemenetById('click-btn')});return(
