最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React報錯Too many re-renders解決

 更新時間:2022年12月15日 17:08:24   作者:chuck  
這篇文章主要為大家介紹了React報錯Too many re-renders解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

總覽

產(chǎn)生"Too many re-renders. React limits the number of renders to prevent an infinite loop"錯誤有多方面的原因:

  • 在一個組件的渲染方法中調(diào)用一個設(shè)置狀態(tài)的函數(shù)。
  • 立即調(diào)用一個事件處理器,而不是傳遞一個函數(shù)。
  • 有一個無限設(shè)置與重渲染的useEffect鉤子。

too-many-re-renders-react-limits-the-number.png

這里有個示例來展示錯誤是如何發(fā)生的:

import {useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  // ?? Too many re-renders. React limits the number
  // of renders to prevent an infinite loop.
  return (
    <div>
      <button onClick={setCounter(counter + 1)}>Increment</button>
      <h1>Count: {counter}</h1>
    </div>
  );
}

上述代碼問題在于,我們在onClick事件處理器中立即調(diào)用了setCounter函數(shù)。

該函數(shù)是在頁面加載時立即被調(diào)用,而不是事件觸發(fā)后調(diào)用。

傳遞函數(shù)

為了解決該錯誤,為onClick事件處理器傳遞函數(shù),而不是傳遞調(diào)用函數(shù)的結(jié)果。

import {useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  return (
    <div>
      <button onClick={() => setCounter(counter + 1)}>Increment</button>
      <h1>Count: {counter}</h1>
    </div>
  );
}

現(xiàn)在,我們?yōu)槭录幚砥鱾鬟f了函數(shù),而不是當(dāng)頁面加載時調(diào)用setCounter方法。

如果該方法在頁面加載時被調(diào)用,就會觸發(fā)一個setState動作,組件就會無限重新渲染。

如果我們試圖立即設(shè)置一個組件的狀態(tài),而不使用一個條件或事件處理器,也會發(fā)生這個錯誤。

import {useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  // ?? Too many re-renders. React limits the number
  // of renders to prevent an infinite loop.
  setCounter(counter + 1);
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

問題在于,setCounter函數(shù)在組件渲染時被調(diào)用、更新狀態(tài),并導(dǎo)致重新渲染,而且是無限重新渲染。

你可以通過向useState()鉤子傳遞一個初始值或一個函數(shù)來初始化狀態(tài),從而解決這個錯誤。

import {useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(() => 100 + 100);
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

我們向useState方法傳遞了一個函數(shù)。這個函數(shù)只會在組件第一次渲染時被調(diào)用,并且會計算出初始狀態(tài)。你也可以直接向useState方法傳遞一個初始值。

另外,你也可以像前面的例子那樣使用一個條件或事件處理器。

import {useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  // ??? your condition here
  if (Math.random() > 0.5) {
    setCounter(counter + 1);
  }
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

如果你像上面的例子那樣使用一個條件,請確保該條件不總是返回一個真值,因為這將導(dǎo)致無限的重新渲染循環(huán)。

"Too many re-renders. React limits the number of renders to prevent an infinite loop"錯誤也會在使用useEffect方法時發(fā)生,該方法的依賴會導(dǎo)致無限重新渲染。

import {useEffect, useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  useEffect(() => {
  // ?? Too many re-renders. React limits the number
  // of renders to prevent an infinite loop.
    setCounter(counter + 1);
  }); // ??? forgot to pass dependency array
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

上述代碼問題在于,我們沒有為useEffect鉤子傳遞依賴數(shù)組。

這意味著該鉤子會在每次渲染時運行,它會更新組件的狀態(tài),然后無限重新運行。

傳遞依賴

解決該錯誤的一種辦法是,為useEffect提供空數(shù)組作為第二個參數(shù)。

import {useEffect, useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  useEffect(() => {
    setCounter(counter + 1);
  }, []); // ??? empty dependencies array
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

如果你為useEffect方法傳遞空數(shù)組依賴作為第二個參數(shù),該方法只在組件的初始渲染時運行。

該代碼將計數(shù)器遞增到1,并且不再運行,無論App組件是否被重新渲染。

如果你必須指定一個依賴來無限地重新渲染你的組件,試著尋找一個可以防止這種情況的條件。

import {useEffect, useState} from 'react';
export default function App() {
  const [counter, setCounter] = useState(0);
  useEffect(() => {
    // ??? some condition here
    if (Math.random() > 0.5) {
      setCounter(counter + 1);
    }
  }, [counter]);
  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

有可能是某些邏輯決定了狀態(tài)是否應(yīng)該被更新,而狀態(tài)不應(yīng)該在每次重新渲染時被設(shè)置。

確保你沒有使用一個在每次渲染時都不同的對象或數(shù)組作為useEffect鉤子的依賴。

import {useEffect, useState} from 'react';
export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});
  const obj = {country: 'Chile', city: 'Santiago'};
  useEffect(() => {
    // ?? Too many re-renders. React limits the number
    // of renders to prevent an infinite loop.
    setAddress(obj);
    console.log('useEffect called');
  }, [obj]);
  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

問題在于,在JavaScript中,對象是通過引用進(jìn)行比較的。obj變量存儲了一個具有相同鍵值對的對象,但每次渲染時的引用不同(在內(nèi)存中的位置不同)。

移入依賴

解決該錯誤的一種辦法是,把這個對象移到useEffect鉤子里面,這樣我們就可以把它從依賴數(shù)組中移除。

import {useEffect, useState} from 'react';
export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});
  useEffect(() => {
    // ??? move object inside of useEffect
    // and remove it from dependencies array
    const obj = {country: 'Chile', city: 'Santiago'};
    setAddress(obj);
    console.log('useEffect called');
  }, []);
  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

傳遞對象屬性

另一個解決方案是將對象的屬性傳遞給依賴數(shù)組。

import {useEffect, useState} from 'react';
export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});
  const obj = {country: 'Chile', city: 'Santiago'};
  useEffect(() => {
    setAddress({country: obj.country, city: obj.city});
    console.log('useEffect called');
    // ??? object properties instead of the object itself
  }, [obj.country, obj.city]);
  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

現(xiàn)在React不是在測試一個對象是否發(fā)生了變化,而是在測試obj.countryobj.city字符串在渲染之間是否發(fā)生了變化。

記憶值

另外,我們可以使用useMemo鉤子來獲得一個在不同渲染之間不會改變的記憶值。

import {useEffect, useMemo, useState} from 'react';
export default function App() {
  const [address, setAddress] = useState({country: '', city: ''});
  // ??? get memoized value
  const obj = useMemo(() => {
    return {country: 'Chile', city: 'Santiago'};
  }, []);
  useEffect(() => {
    setAddress(obj);
    console.log('useEffect called');
  }, [obj]);
  return (
    <div>
      <h1>Country: {address.country}</h1>
      <h1>City: {address.city}</h1>
    </div>
  );
}

我們將對象的初始化包裹在useMemo鉤子里面,以獲得一個不會在渲染之間改變的記憶值。

我們傳遞給useMemo鉤子的第二個參數(shù)是一個依賴數(shù)組,它決定了我們傳遞給useMemo的回調(diào)函數(shù)何時被重新運行。

需要注意的是,數(shù)組在JavaScript中也是通過引用進(jìn)行比較的。所以一個具有相同值的數(shù)組也可能導(dǎo)致你的useEffect鉤子被無限次觸發(fā)。

import {useEffect, useMemo, useState} from 'react';
export default function App() {
  const [nums, setNums] = useState([1, 2, 3]);
  const arr = [4, 5, 6];
  useEffect(() => {
    // ?? Too many re-renders. React limits the number
    // of renders to prevent an infinite loop.
    setNums(arr);
    console.log('useEffect called');
  }, [arr]);
  return <div>{nums[0]}</div>;
}

數(shù)組在重新渲染之間存儲相同的值,但指向內(nèi)存中的不同位置,并且在每次組件重新渲染時有不同的引用。

在處理數(shù)組時,我們用于對象的方法同樣有效。例如,我們可以使用useMemo鉤子來獲得一個在渲染之間不會改變的記憶值。

import {useEffect, useMemo, useState} from 'react';
export default function App() {
  const [nums, setNums] = useState([1, 2, 3]);
  const arr = useMemo(() => {
    return [4, 5, 6];
  }, []);
  useEffect(() => {
    setNums(arr);
    console.log('useEffect called');
  }, [arr]);
  return <div>{nums[0]}</div>;
}

我們將數(shù)組的初始化包裹在useMemo鉤子里面,以獲得一個不會在不同渲染之間改變的記憶值。

以上就是React報錯Too many re-renders解決的詳細(xì)內(nèi)容,更多關(guān)于React報錯Too many re-renders的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react如何實現(xiàn)篩選條件組件

    react如何實現(xiàn)篩選條件組件

    這篇文章主要介紹了react如何實現(xiàn)篩選條件組件問題,具有很好的參考價價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • React錯誤的習(xí)慣用法分析詳解

    React錯誤的習(xí)慣用法分析詳解

    這篇文章主要為大家介紹了React錯誤用法習(xí)慣分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • ReactNative短信驗證碼倒計時控件的實現(xiàn)代碼

    ReactNative短信驗證碼倒計時控件的實現(xiàn)代碼

    本篇文章主要介紹了ReactNative短信驗證碼倒計時控件的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • React安裝node-sass失敗解決方案分享

    React安裝node-sass失敗解決方案分享

    Node-sass是一個庫,它將Node.js綁定到LibSass(流行樣式表預(yù)處理器Sass的C版本),它允許用戶以令人難以置信的速度將.scss文件本地編譯為css,并通過連接中間件自動編譯,下面這篇文章主要給大家介紹了關(guān)于React安裝node-sass失敗解決的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • React和Vue的props驗證示例詳解

    React和Vue的props驗證示例詳解

    這篇文章主要介紹了React和Vue的props驗證,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • ForwardRef?useImperativeHandle方法demo

    ForwardRef?useImperativeHandle方法demo

    這篇文章主要為大家介紹了ForwardRef?useImperativeHandle方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 基于React封裝一個驗證碼輸入控件

    基于React封裝一個驗證碼輸入控件

    郵箱、手機(jī)驗證碼輸入是許多在線服務(wù)和網(wǎng)站常見的安全驗證方式之一,本文主要來和大家討論一下如何使用React封裝一個驗證碼輸入控件,感興趣的可以了解下
    2024-03-03
  • react-redux中connect()方法詳細(xì)解析

    react-redux中connect()方法詳細(xì)解析

    connect()是React-redux中的核心方法之一,它將react組件預(yù)redux中的Store真正連接在一起,下面這篇文章主要給大家介紹了react-redux中connect()方法的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-05-05
  • 一文詳解React Redux設(shè)計思想與工作原理

    一文詳解React Redux設(shè)計思想與工作原理

    最近看項目中使用了?Redux,?便嘗試了解一波?Redux?的設(shè)計思想與工作原理,所以本文詳細(xì)的給大家介紹了Redux設(shè)計思想與工作原理,需要的朋友可以參考下
    2023-09-09
  • webpack打包react項目的實現(xiàn)方法

    webpack打包react項目的實現(xiàn)方法

    這篇文章主要介紹了webpack打包react項目的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06

最新評論

皮山县| 大余县| 天等县| 耿马| 金沙县| 孟连| 红河县| 万源市| 类乌齐县| 家居| 准格尔旗| 昌图县| 鄂托克前旗| 汉寿县| 安西县| 剑川县| 沙洋县| 鸡东县| 石嘴山市| 洛隆县| 海伦市| 洛浦县| 舞钢市| 湘西| 惠安县| 澜沧| 德州市| 托里县| 景德镇市| 乌恰县| 永州市| 沙雅县| 余干县| 南木林县| 滨海县| 温泉县| 牙克石市| 邛崃市| 丹东市| 宜黄县| 西乡县|