成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

五種有趣的 UseEffect 無限循環類型

開發 前端
一般來說,無限循環被認為是不好的做法。但在一些邊界 case 中,你沒有任何選擇,只能選擇無限循環。了解 React 的無限循環模式是件好事。

[[426317]]

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

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

useEffect

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

只有當依賴關系被改變時,useEffect hook 才會觸發回調函數。而且它使用淺比較法來比較 hooks 的值。

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

缺失依賴

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

思考一下下面的代碼,它將一直調用 API。

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

會發生什么

如果 useEffect 只有在依賴關系發生變化時才觸發回調,那為什么我們在這里會出現無限循環?

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

在這段代碼中,我們使用 setData 在網絡調用成功后設置狀態值,它將觸發組件的重新渲染。由于 useEffect 沒有值可以比較,所以它將調用回調。

Fetch 將再次觸發setData,setData將觸發組件重新渲染,如此反復。

如何修復這個問題?

我們需要將依賴指定為空數組。

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

根據官方文檔,省略依賴關系是不安全的

依賴性的作用

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

  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.     <div className="App"
  13.       <h1>Hello CodeSandbox</h1> 
  14.       <button onClick={() => setCount(count + 1)}>{count}</button> 
  15.       <h2>Start editing to see some magic happen!</h2> 
  16.     </div> 
  17.   ); 

函數 getData 作為依賴項被傳入。

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

發生了什么?

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

如何修復這個問題?

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

useCallback 返回一個memoized 版本的回調,只在依賴關系改變時才會改變。

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

將數組作為依賴

你可能知道,二者的淺層比較總是假的,所以以數組形式傳遞依賴關系也會導致 “無限循環”。

讓我們看看以下代碼

  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.     <div className="App"
  12.       <h1>Hello CodeSandbox</h1> 
  13.       <button onClick={() => setCount(count + 1)}>{count}</button> 
  14.       <h2>Start editing to see some magic happen!</h2> 
  15.     </div> 
  16.   ); 

這里,數組 dep 作為 useEffect 的依賴傳入。

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

發生了什么?

兩個數組的淺層比較總是假的,所以 useEffect 總是會觸發回調。

如果修復這個問題?

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

那么,我們應該怎么辦?

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

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

將對象作為依賴

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

讓我們看看一下這段代碼

  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 的依賴項傳入的。

當你運行這段代碼時,你的瀏覽器控制臺將被拋出一個無限循環的錯誤。

這里發生了什么?

對象的淺層比較將永遠是假的,所以它將觸發 useEffect 的回調。

如果修復這個問題?

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

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

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

  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.     <div className="App"
  17.       <h1>Hello CodeSandbox</h1> 
  18.       <button onClick={() => setCount(count + 1)}>{count}</button> 
  19.       <h2>Start editing to see some magic happen!</h2> 
  20.     </div> 
  21.   ); 

錯誤的依賴

錯誤的依賴關系與 React 無關,甚至與 javascript 無關。當使用錯誤的依賴關系時,我們必須承擔起責任。

讓我們看看一下這段代碼

  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; 

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

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

總是使用 eslint-plugin-react-hooks 或 create-react-app,它將幫助你在這些問題進入生產環境之前找到這些問題。

一家公司在一周內因無限循環而損失了 $ 7.2 w。

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

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

本文轉載自微信公眾號「前端鐵蛋」,可以通過以下二維碼關注。轉載本文請聯系前端鐵蛋公眾號。

 

責任編輯:武曉燕 來源: 前端鐵蛋
相關推薦

2021-04-01 08:05:01

React無限循環useEffect()

2021-06-07 14:05:53

物聯網IOT物聯網技術

2022-10-10 23:19:02

Python腳本語言工具庫

2021-07-08 09:17:07

物聯網人工智能IoT

2024-01-02 07:56:13

ReactuseEffect數據驅動 UI

2015-07-23 11:26:35

虛擬化負載類型

2023-08-22 13:18:00

Web 開發CSS

2023-04-14 14:54:29

2023-11-17 08:00:00

公共云云計算

2023-07-04 15:11:30

TypeScript類型保護

2009-08-25 14:25:19

Eclipse 3.5

2023-08-13 08:29:27

ChatGPT指令AI

2010-03-11 14:15:24

Python循環

2012-05-10 14:02:46

jQuery

2015-07-21 12:30:15

Swift輪播圖無限循環

2023-12-22 10:53:08

2022-12-09 08:00:00

深度學習人工智能機器學習

2022-07-28 08:33:59

JupyterPython

2023-07-19 09:50:25

人工智能算法

2012-05-28 09:16:12

Java設計模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 最新av片| 在线一区二区三区 | 韩日精品视频 | 国产日韩一区二区三区 | 久久久久久成人 | 99色综合 | 亚洲一区二区三区在线播放 | 色999视频 | 日韩在线观看精品 | 国产91久久久久蜜臀青青天草二 | 9久久精品 | 色婷婷综合久久久中字幕精品久久 | 一区二区中文 | 超碰成人免费 | 日韩一区二区三区在线播放 | 波多野结衣一区二区 | 亚洲一区二区三区四区在线观看 | 国产亚洲一区二区三区在线观看 | 日韩一区二区在线免费观看 | 久久在看 | 亚洲成人观看 | 欧美日韩综合一区 | 在线观看免费av片 | 国产精品久久久久久一区二区三区 | 91精品国产91久久久久青草 | 亚洲第一视频网 | 99精品视频免费观看 | 国产羞羞视频在线观看 | 一区二区三区欧美在线观看 | 自拍偷拍精品 | 日批的视频 | 黄色一级毛片 | 免费成人午夜 | 久产久精国产品 | 91久久 | 日本成人区 | 中文字幕av在线 | 国产视频久久 | 婷婷中文在线 | 日韩在线视频一区 | 日韩精品免费 |