日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
ReactHooks在SSR模式下常見問題及解決方案

服務(wù)端渲染(Server-Side Rendering),是指由服務(wù)側(cè)完成頁面的 HTML 結(jié)構(gòu)拼接的頁面處理技術(shù)。一般用于解決 SEO 問題和首屏加載速度問題。

由于 SSR 是在非瀏覽器環(huán)境執(zhí)行 JS 代碼,所以會(huì)出現(xiàn)很多問題。本文主要介紹 React Hooks 在 SSR 模式下常見問題及解決方案。

更多關(guān)于 SSR 的介紹可以看 UmiJS 的文檔《服務(wù)端渲染(SSR)[1]》。

問題一:DOM/BOM 缺失

SSR 是在 node 環(huán)境下運(yùn)行 React 代碼,而此時(shí) window、document、navigator 等全局屬性沒有。如果直接使用了這些屬性,就會(huì)報(bào)錯(cuò) window is not defined, document is not defined, navigator is not defined 等。

常見的錯(cuò)誤用法是在 Hooks 執(zhí)行過程中,直接使用了 document 等全局屬性。

 
 
 
 
  1. import React, { useState } from 'react';
  2. export default () => {
  3.   const [state, setState] = useState(document.visibilityState);
  4.   return state;
  5. }

解決方案

1.將訪問 DOM/BOM 的方法放在 useEffect/useLayoutEffect 中(服務(wù)端不會(huì)執(zhí)行),避免服務(wù)端執(zhí)行時(shí)報(bào)錯(cuò),例如:

 
 
 
 
  1. import React, { useState, useEffect } from 'react';
  2. export default () => {
  3.   const [state, setState] = useState();
  4.   
  5.   useEffect(()=>{
  6.     setState(document.visibilityState);
  7.   }, []);
  8.   
  9.   return state;
  10. }

2.通過 isBrowser[2]來做環(huán)境判斷

 
 
 
 
  1. import React, { useState } from 'react';
  2. function isBrowser() {
  3.   return !!(typeof window !== 'undefined' && window.document && window.document.createElement);
  4. }
  5. export default () => {
  6.   const [state, setState] = useState(isBrowser() && document.visibilityState);
  7.   
  8.   return state;
  9. }

問題二 useLayoutEffect Warning

如果使用了 useLayoutEffect,在 SSR 模式下,會(huì)出現(xiàn)以下警告

  • ? Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://fb.me/react-uselayouteffect-SSR for common fixes.

解決方案

  1. 使用 useEffect 代替 useLayoutEffect(廢話)
  2. 根據(jù)環(huán)境動(dòng)態(tài)的指定是使用 useEffect 還是 useLayoutEffect。這是來自社區(qū)的一種 hack 解決方案,目前在react-redux[3]、react-use[4]、react-beautiful-dnd[5]均使用的這種方案。
 
 
 
 
  1. import { useLayoutEffect, useEffect } from 'react';
  2. const useIsomorphicLayoutEffect = isBrowser() ? useLayoutEffect : useEffect;
  3. export default useIsomorphicLayoutEffect;

總結(jié):寫 Hooks 時(shí)需要注意

1.不要在非 useEffect/useLayoutEffect 中,直接使用 DOM/BOM 屬性

2.在非 useEffect/useLayoutEffect 使用 DOM/BOM 屬性時(shí),使用 isBrowser 判斷是否在瀏覽器環(huán)境執(zhí)行

3.如果某個(gè) Hooks 需要接收 DOM/BOM 屬性,需要支持函數(shù)形式傳參。以 ahooks 的 useEventListener 舉例,必須支持函數(shù)形式來指定 target 屬性。

 
 
 
 
  1. import React, { useState } from 'react';
  2. import { useEventListener } from 'ahooks';
  3. export default () => {
  4.   const [value, setValue] = useState(0);
  5.   const clickHandler = () => {
  6.     setValue(value + 1);
  7.   };
  8.   useEventListener(
  9.     'click', 
  10.     clickHandler, 
  11.     { 
  12. -       target: document.getElemenetById('click-btn') 
  13. +       target: () => document.getElemenetById('click-btn') 
  14.     }
  15.   );
  16.   return (
  17.     
  18.       You click {value} times
  19.     
  20.   );
  21. };

4.使用 useIsomorphicLayoutEffect 來代替 useLayoutEffect

參考資料

  • fix: useDocumentVisiblility support SSR[6]
  • UmiJS 服務(wù)端渲染[7]
  • useLayoutEffect and SSR[8]

參考資料

[1]服務(wù)端渲染(SSR):

https://umijs.org/zh-CN/docs/SSR#服務(wù)端渲染(SSR)

[2]isBrowser:

https://github.com/alibaba/hooks/blob/master/packages/hooks/src/utils/canUseDom.ts

[3]react-redux:

https://github.com/reduxjs/react-redux/blob/d16262582b2eeb62c05313fca3eb59dc0b395955/src/components/connectAdvanced.js#L40

[4]react-use:

https://github.com/streamich/react-use/blob/master/src/useIsomorphicLayoutEffect.ts

[5]react-beautiful-dnd:

https://github.com/atlassian/react-beautiful-dnd/blob/master/src/view/use-isomorphic-layout-effect.js

[6]fix: useDocumentVisiblility support SSR:

https://github.com/alibaba/hooks/pull/935/files

[7]UmiJS 服務(wù)端渲染:

https://umijs.org/zh-CN/docs/SSR#window-is-not-defined-document-is-not-defined-navigator-is-not-defined

[8]useLayoutEffect and SSR:

https://medium.com/@alexandereardon/uselayouteffect-and-SSR-192986cdcf7a

本文轉(zhuǎn)載自微信公眾號「前端技術(shù)磚家」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系前端技術(shù)磚家公眾號。


當(dāng)前文章:ReactHooks在SSR模式下常見問題及解決方案
標(biāo)題鏈接:http://m.5511xx.com/article/cdjocgp.html