91在线一级黄片|91视频在线观看18|成人夜间呦呦网站|91资源欧美日韩超碰|久久最新免费精品视频一区二区三区|国产探花视频在线观看|黄片真人免费三级片毛片|国产人无码视频在线|精品成人影视无码三区|久久视频爱久久免费精品

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
五種有趣的UseEffect無限循環(huán)類型

一般來說,無限循環(huán)被認(rèn)為是不好的做法。但在一些邊界 case 中,你沒有任何選擇,只能選擇無限循環(huán)。了解 React 的無限循環(huán)模式是件好事。

當(dāng)無限循環(huán)沒有無法停止時,最終瀏覽器會殺死你的代碼正在運行的標(biāo)簽。所以不要使用沒有任何斷點的 “無限循環(huán)”。

useEffect

useEffect hook 允許我們在一個組件中表現(xiàn)出副作用。當(dāng) hooks 被引入 react 16 時,useEffect hooks 比其他 hooks 更有吸引力。因為它提供了 componentDidMount、componentDidUpdate 和 componentWillUnmount 生命周期方法的綜合功能。

只有當(dāng)依賴關(guān)系被改變時,useEffect hook 才會觸發(fā)回調(diào)函數(shù)。而且它使用淺比較法來比較 hooks 的值。

你可以把 useEffect 看作是一塊能量石,它是一塊最強大的石頭,如果你沒有正確地處理它,這塊石頭會摧毀你。

缺失依賴

缺失依賴關(guān)系的 useEffect 通常被認(rèn)為是一種不好的做法,所以總是盡量避免它。

思考一下下面的代碼,它將一直調(diào)用 API。

 
 
 
 
  1. useEffect(() => { 
  2.   fetch("/api/user") 
  3.     .then((res) => res.json) 
  4.     .then((res) => { 
  5.       setData(res); 
  6.     }); 
  7. }); 

會發(fā)生什么

如果 useEffect 只有在依賴關(guān)系發(fā)生變化時才觸發(fā)回調(diào),那為什么我們在這里會出現(xiàn)無限循環(huán)?

你需要考慮到 React 的另一個重要的法則,即 “當(dāng) state 或 props 發(fā)生變化時,組件將重新渲染”。

在這段代碼中,我們使用 setData 在網(wǎng)絡(luò)調(diào)用成功后設(shè)置狀態(tài)值,它將觸發(fā)組件的重新渲染。由于 useEffect 沒有值可以比較,所以它將調(diào)用回調(diào)。

Fetch 將再次觸發(fā)setData,setData將觸發(fā)組件重新渲染,如此反復(fù)。

如何修復(fù)這個問題?

我們需要將依賴指定為空數(shù)組。

 
 
 
 
  1. useEffect(() => { 
  2.   fetch("/api/user") 
  3.     .then((res) => res.json) 
  4.     .then((res) => { 
  5.       setData(res); 
  6.     }); 
  7. }, []); // <- dependencies 

根據(jù)官方文檔,省略依賴關(guān)系是不安全的

依賴性的作用

useEffect 使用淺層對象比較來確定數(shù)據(jù)是否被改變。因為奇怪的 JavaScript 條件判斷系統(tǒng) ??。

 
 
 
 
  1. var mark1 = function () { 
  2.   return "100"; 
  3. }; // 唯一的對象引用 
  4. var mark2 = function () { 
  5.   return "100"; 
  6. }; // 唯一的對象引用 
  7. mark1 == mark2; // false 
  8. mark1 === mark2; // false 

讓我們看看以下代碼

 
 
 
 
  1. import React, { useCallback, useEffect, useState } from "react"; 
  2. export default function App() { 
  3.   const [count, setCount] = useState(0); 
  4.   const getData = () => { 
  5.     return window.localStorage.getItem("token"); 
  6.   }; 
  7.   const [dep, setDep] = useState(getData()); 
  8.   useEffect(() => { 
  9.     setCount(count + 1); 
  10.   }, [getData]); 
  11.   return ( 
  12.      
  13.       

    Hello CodeSandbox

     
  14.        setCount(count + 1)}>{count} 
  15.       

    Start editing to see some magic happen!

     
  16.     
 
  •   ); 
  • 函數(shù) getData 作為依賴項被傳入。

    當(dāng)你運行這段代碼時,它將拋出 “超過最大更新” 的錯誤,這意味著代碼有一個無限循環(huán)。

    發(fā)生了什么?

    由于 useEffect 使用淺層比較法來比較數(shù)值。該函數(shù)的淺層比較將總是給出 false。

    如何修復(fù)這個問題?

    為了修復(fù)這個問題,我們需要使用另一個叫做 useCallback 的 hook。

    useCallback 返回一個memoized 版本的回調(diào),只在依賴關(guān)系改變時才會改變。

     
     
     
     
    1. const getData = useCallback(() => { 
    2.   return window.localStorage.getItem("token"); 
    3. }, []); // <- dependencies 

    將數(shù)組作為依賴

    你可能知道,二者的淺層比較總是假的,所以以數(shù)組形式傳遞依賴關(guān)系也會導(dǎo)致 “無限循環(huán)”。

    讓我們看看以下代碼

     
     
     
     
    1. import React, { useCallback, useEffect, useState } from "react"; 
    2. export default function App() { 
    3.   const [count, setCount] = useState(0); 
    4.   const dep = ["a"]; 
    5.   const [value, setValue] = useState(["b"]); 
    6.   useEffect(() => { 
    7.     setValue(["c"]); 
    8.   }, [dep]); 
    9.  
    10.   return ( 
    11.      
    12.       

      Hello CodeSandbox

       
    13.        setCount(count + 1)}>{count} 
    14.       

      Start editing to see some magic happen!

       
    15.     
     
  •   ); 
  • 這里,數(shù)組 dep 作為 useEffect 的依賴傳入。

    當(dāng)你運行這段代碼時,瀏覽器控制臺會拋出這個錯誤。

    發(fā)生了什么?

    兩個數(shù)組的淺層比較總是假的,所以 useEffect 總是會觸發(fā)回調(diào)。

    如果修復(fù)這個問題?

    由于 useCallback 的返回是一個函數(shù),我們不能使用。

    那么,我們應(yīng)該怎么辦?

    我們需要使用另一個名為 useRef 的 hook

    useRef 返回一個可變的對象,.current 具有初始值。

    將對象作為依賴

    你可能會猜到兩個對象的淺層比較總是假的,所以 useEffect 會一直觸發(fā)回調(diào)。

    讓我們看看一下這段代碼

     
     
     
     
    1. import React, { useEffect, useState, useRef } from "react"; 
    2. export default function Home() { 
    3.   const [value, setValue] = useState(["b"]); 
    4.   const { current: a } = useRef(["a"]); 
    5.   useEffect(() => { 
    6.     setValue(["c"]); 
    7.   }, [a]); 

    data 是作為 useEffect 的依賴項傳入的。

    當(dāng)你運行這段代碼時,你的瀏覽器控制臺將被拋出一個無限循環(huán)的錯誤。

    這里發(fā)生了什么?

    對象的淺層比較將永遠(yuǎn)是假的,所以它將觸發(fā) useEffect 的回調(diào)。

    如果修復(fù)這個問題?

    如果我們將依賴關(guān)系備忘化,我們就能打破無限循環(huán)。那么,如何做到這一點呢?

    是的,我們將使用另一個名為 useMemo 的 hook。

    useMemo 只有在依賴關(guān)系發(fā)生變化時才會重新計算記憶化的值。

     
     
     
     
    1. import React, { useMemo, useEffect, useState } from "react"; 
    2.  
    3. export default function App() { 
    4.   const [count, setCount] = useState(0); 
    5.   const data = useMemo( 
    6.     () => ({ 
    7.       is_fetched: false, 
    8.     }), 
    9.     [] 
    10.   ); // <- dependencies 
    11.   useEffect(() => { 
    12.     setCount(count + 1); 
    13.   }, [data]); 
    14.  
    15.   return ( 
    16.      
    17.       

      Hello CodeSandbox

       
    18.        setCount(count + 1)}>{count} 
    19.       

      Start editing to see some magic happen!

       
    20.     
     
  •   ); 
  • 錯誤的依賴

    錯誤的依賴關(guān)系與 React 無關(guān),甚至與 javascript 無關(guān)。當(dāng)使用錯誤的依賴關(guān)系時,我們必須承擔(dān)起責(zé)任。

    讓我們看看一下這段代碼

     
     
     
     
    1. import React, { useEffect, useState } from "react"; 
    2. const App = () => { 
    3.   const [text, setText] = useState(""); 
    4.   useEffect(() => { 
    5.     setText(text); 
    6.   }, [text]); 
    7.   return null; 
    8. }; 
    9. export default App; 

    我希望沒有必要解釋這個問題模式和它的修復(fù)方法。如果你想知道解釋和修復(fù)方法,請在評論中告訴我。

    注意:有很多方法可以避免 React 組件內(nèi)部的無限循環(huán),我只提到了幾種方法。

    總是使用 eslint-plugin-react-hooks 或 create-react-app,它將幫助你在這些問題進(jìn)入生產(chǎn)環(huán)境之前找到這些問題。

    一家公司在一周內(nèi)因無限循環(huán)而損失了 $ 7.2 w。

    所以在使用 useEffect 的時候一定要特別小心。

    原文:https://javascript.plainenglish.io/5-useeffect-infinite-loop-patterns-2dc9d45a253f

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


    網(wǎng)站題目:五種有趣的UseEffect無限循環(huán)類型
    當(dāng)前鏈接:http://m.jiaoqi3.com/article/cdespdi.html