真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么解決React.useEffect()的無限循環(huán)

這篇文章主要講解了“怎么解決React.useEffect()的無限循環(huán)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么解決React.useEffect()的無限循環(huán)”吧!

成都創(chuàng)新互聯(lián)公司是一家網(wǎng)站設(shè)計公司,集創(chuàng)意、互聯(lián)網(wǎng)應(yīng)用、軟件技術(shù)為一體的創(chuàng)意網(wǎng)站建設(shè)服務(wù)商,主營產(chǎn)品:成都響應(yīng)式網(wǎng)站建設(shè)公司成都品牌網(wǎng)站建設(shè)、營銷型網(wǎng)站。我們專注企業(yè)品牌在網(wǎng)站中的整體樹立,網(wǎng)絡(luò)互動的體驗,以及在手機(jī)等移動端的優(yōu)質(zhì)呈現(xiàn)。網(wǎng)站設(shè)計制作、網(wǎng)站設(shè)計、移動互聯(lián)產(chǎn)品、網(wǎng)絡(luò)運營、VI設(shè)計、云產(chǎn)品.運維為核心業(yè)務(wù)。為用戶提供一站式解決方案,我們深知市場的競爭激烈,認(rèn)真對待每位客戶,為客戶提供賞析悅目的作品,網(wǎng)站的價值服務(wù)。

1. 無限循環(huán)和副作用更新狀態(tài)

假設(shè)我們有一個功能組件,該組件里面有一個 input 元素,組件是功能是計算 input 更改的次數(shù)。

我們給這個組件取名為 CountInputChanges,大概的內(nèi)容如下:

function CountInputChanges() {   const [value, setValue] = useState('');   const [count, setCount] = useState(-1);   useEffect(() => setCount(count + 1));   const onChange = ({ target }) => setValue(target.value);    return (     
    
Number of changes: {count}
  
   ) }

是受控組件。value變量保存著 input  輸入的值,當(dāng)用戶輸入輸入時,onChange事件處理程序更新 value 狀態(tài)。

這里使用useEffect()更新count變量。每次由于用戶輸入而導(dǎo)致組件重新渲染時,useEffect(() => setCount(count  + 1))就會更新計數(shù)器。

因為useEffect(() => setCount(count + 1))是在沒有依賴參數(shù)的情況下使用的,所以()=>  setCount(count + 1)會在每次渲染組件后執(zhí)行回調(diào)。

你覺得這樣寫會有問題嗎?打開演示自己試試看:https://codesandbox.io/s/infinite-loop-9rb8c?file=/src/App.js

運行了會發(fā)現(xiàn)count狀態(tài)變量不受控制地增加,即使沒有在input中輸入任何東西,這是一個無限循環(huán)。怎么解決React.useEffect()的無限循環(huán)

問題在于useEffect()的使用方式:

useEffect(() => setCount(count + 1));

它生成一個無限循環(huán)的組件重新渲染。

在初始渲染之后,useEffect()執(zhí)行更新狀態(tài)的副作用回調(diào)函數(shù)。狀態(tài)更新觸發(fā)重新渲染。重新渲染之后,useEffect()執(zhí)行副作用回調(diào)并再次更新狀態(tài),這將再次觸發(fā)重新渲染。


1.1通過依賴來解決

無限循環(huán)可以通過正確管理useEffect(callback, dependencies)依賴項參數(shù)來修復(fù)。

因為我們希望count在值更改時增加,所以可以簡單地將value作為副作用的依賴項。

import { useEffect, useState } from 'react';  function CountInputChanges() {   const [value, setValue] = useState('');   const [count, setCount] = useState(-1);   useEffect(() => setCount(count + 1), [value]);   const onChange = ({ target }) => setValue(target.value);    return (     
    
Number of changes: {count}
  
   ); }

添加[value]作為useEffect的依賴,這樣只有當(dāng)[value]發(fā)生變化時,計數(shù)狀態(tài)變量才會更新。這樣做可以解決無限循環(huán)。


1.2 使用 ref

除了依賴,我們還可以通過 useRef() 來解決這個問題。

其思想是更新 Ref 不會觸發(fā)組件的重新渲染。

import { useEffect, useState, useRef } from "react";  function CountInputChanges() {   const [value, setValue] = useState("");   const countRef = useRef(0);   useEffect(() => countRef.current++);   const onChange = ({ target }) => setValue(target.value);    return (     
    
Number of changes: {countRef.current}
  
   ); }

useEffect(() => countRef.current++)  每次由于value的變化而重新渲染后,countRef.current++就會返回。引用更改本身不會觸發(fā)組件重新渲染。

2. 無限循環(huán)和新對象引用

即使正確設(shè)置了useEffect()依賴關(guān)系,使用對象作為依賴關(guān)系時也要小心。

例如,下面的組件CountSecrets監(jiān)聽用戶在input中輸入的單詞,一旦用戶輸入特殊單詞'secret',統(tǒng)計 'secret' 的次數(shù)就會加  1。

import { useEffect, useState } from "react";  function CountSecrets() {   const [secret, setSecret] = useState({ value: "", countSecrets: 0 });    useEffect(() => {     if (secret.value === 'secret') {  setSecret(s => ({...s, countSecrets: s.countSecrets + 1}));    }  }, [secret]);   const onChange = ({ target }) => {     setSecret(s => ({ ...s, value: target.value }));   };    return (     
    
Number of secrets: {secret.countSecrets}
  
   ); }

打開演示(https://codesandbox.io/s/infinite-loop-obj-dependency-7t26v?file=/src/App.js)自己試試,當(dāng)前輸入  secret,secret.countSecrets的值就開始不受控制地增長。

這是一個無限循環(huán)問題。

為什么會這樣?

secret對象被用作useEffect(..., [secret])。在副作用回調(diào)函數(shù)中,只要輸入值等于secret,就會調(diào)用更新函數(shù)

setSecret(s => ({...s, countSecrets: s.countSecrets + 1}));

這會增加countSecrets的值,但也會創(chuàng)建一個新對象。

secret現(xiàn)在是一個新對象,依賴關(guān)系也發(fā)生了變化。所以useEffect(...,  [secret])再次調(diào)用更新狀態(tài)和再次創(chuàng)建新的secret對象的副作用,以此類推。

JavaScript 中的兩個對象只有在引用完全相同的對象時才相等。

2.1 避免將對象作為依賴項

解決由循環(huán)創(chuàng)建新對象而產(chǎn)生的無限循環(huán)問題的最好方法是避免在useEffect()的dependencies參數(shù)中使用對象引用。

  1. let count = 0; 

  2.  

  3. useEffect(() => { 

  4.   // some logic 

  5. }, [count]); // Good! 


let myObject = {   prop: 'Value' };  useEffect(() => {   // some logic }, [myObject]); // Not good! useEffect(() => {   // some logic }, [myObject.prop]); // Good!

修復(fù)組件的無限循環(huán)問題,可以將useEffect(..., [secret])) 變?yōu)?useEffect(...,  [secret.value])。

僅在secret.value更改時調(diào)用副作用回調(diào)就足夠了,下面是修復(fù)后的代碼:

import { useEffect, useState } from "react";  function CountSecrets() {   const [secret, setSecret] = useState({ value: "", countSecrets: 0 });    useEffect(() => {     if (secret.value === 'secret') {       setSecret(s => ({...s, countSecrets: s.countSecrets + 1}));     }  }, [secret.value]);   const onChange = ({ target }) => {     setSecret(s => ({ ...s, value: target.value }));   };    return (     
    
Number of secrets: {secret.countSecrets}
  
   ); }

 3 總結(jié)

useEffect(callback, deps)是在組件渲染后執(zhí)行callback(副作用)的  Hook。如果不注意副作用的作用,可能會觸發(fā)組件渲染的無限循環(huán)。

生成無限循環(huán)的常見情況是在副作用中更新狀態(tài),沒有指定任何依賴參數(shù)

useEffect(() => {   // Infinite loop!   setState(count + 1); });

避免無限循環(huán)的一種有效方法是正確設(shè)置依賴項:

useEffect(() => {   // No infinite loop   setState(count + 1); }, [whenToUpdateValue]);

另外,也可以使用 Ref,更新 Ref 不會觸發(fā)重新渲染:

useEffect(() => {   // No infinite loop   countRef.current++; });

無限循環(huán)的另一種常見方法是使用對象作為useEffect()的依賴項,并在副作用中更新該對象(有效地創(chuàng)建一個新對象)

useEffect(() => {   // Infinite loop!   setObject({     ...object,     prop: 'newValue'   }) }, [object]);

避免使用對象作為依賴項,只使用特定的屬性(最終結(jié)果應(yīng)該是一個原始值):

useEffect(() => {   // No infinite loop   setObject({     ...object,     prop: 'newValue'   }) }, [object.whenToUpdateProp]);

當(dāng)使用useEffect()時,你還知道有其它方式會引起無限循環(huán)陷阱嗎?

感謝各位的閱讀,以上就是“怎么解決React.useEffect()的無限循環(huán)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么解決React.useEffect()的無限循環(huán)這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


當(dāng)前名稱:怎么解決React.useEffect()的無限循環(huán)
轉(zhuǎn)載注明:http://weahome.cn/article/ppjjeh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部