解決React報(bào)錯(cuò)Rendered more hooks than during the previous render
總覽
當(dāng)我們有條件地調(diào)用一個(gè)鉤子或在所有鉤子運(yùn)行之前提前返回時(shí),會(huì)產(chǎn)生"Rendered more hooks than during the previous render"錯(cuò)誤。為了解決該錯(cuò)誤,將所有的鉤子移到函數(shù)組件的頂層,以及不要在條件中使用鉤子。
這里有個(gè)示例用來(lái)展示錯(cuò)誤是如何發(fā)生的。
// App.js import {useEffect, useState} from 'react'; export default function App() { const [counter, setCounter] = useState(0); // ?? Error: Rendered more hooks than during the previous render. if (counter > 0) { // ??? calling React hook conditionally useEffect(() => { console.log('hello world'); }); } return ( <div> <button onClick={() => setCounter(counter + 1)}>toggle loading</button> <h1>Hello world</h1> </div> ); }
代碼的問(wèn)題在于,我們有條件地調(diào)用了useEffect
鉤子。
頂層調(diào)用
為了解決該錯(cuò)誤,我們必須將條件移到鉤子內(nèi)部。因?yàn)镽eact鉤子只能在頂層調(diào)用。
import {useEffect, useState} from 'react'; export default function App() { const [counter, setCounter] = useState(0); // ? hook is called at top level (not conditionally) useEffect(() => { if (counter > 0) { console.log('hello world'); } }); return ( <div> <button onClick={() => setCounter(counter + 1)}>toggle loading</button> <h1>Hello world</h1> </div> ); }
我們將if
語(yǔ)句移動(dòng)到了useEffect
鉤子內(nèi)部。
這就解決了錯(cuò)誤,因?yàn)槲覀儽仨毚_保每次組件渲染時(shí),React鉤子都以相同的順序被調(diào)用。
這意味著我們不允許在循環(huán)、條件或嵌套函數(shù)中使用鉤子。
這里有另外一個(gè)示例用來(lái)展示錯(cuò)誤是如何發(fā)生的。
import {useState} from 'react'; export default function App() { const [counter, setCounter] = useState(0); // ??? this returns before second hook runs if condition is met if (counter > 0) { return <h2>Returning early</h2>; } // ?? Error because hook is called conditionally const [color, setColor] = useState('salmon'); return ( <div> <button onClick={() => setCounter(counter + 1)}>toggle loading</button> <h1>Hello world</h1> </div> ); }
問(wèn)題在于,第二個(gè)useState
鉤子只有在上面的條件沒(méi)有滿足時(shí)才會(huì)被調(diào)用。
條件之上
為了解決這個(gè)錯(cuò)誤,把所有的鉤子移到組件的頂層,在任何可能返回值的條件之上。
import {useState} from 'react'; export default function App() { const [counter, setCounter] = useState(0); const [color, setColor] = useState('salmon'); // ??? condition that may return early must be below all hooks if (counter > 0) { return <h2>Returning early</h2>; } return ( <div> <button onClick={() => setCounter(counter + 1)}>toggle loading</button> <h1>Hello world</h1> </div> ); }
我們把第二個(gè)useState
鉤子移動(dòng)到有可能返回一個(gè)值的if
條件上面。
這是很有幫助的,因?yàn)殂^子現(xiàn)在在頂層,并且有可預(yù)測(cè)的行為,允許React在調(diào)用useState
和useEffect
之間正確地保存狀態(tài)。
就像文檔中所說(shuō)的那樣:
- 只從React函數(shù)組件或自定義鉤子中調(diào)用Hook
- 只在最頂層使用 Hook
- 不要在循環(huán),條件或嵌套函數(shù)中調(diào)用 Hook
- 確保總是在你的 React 函數(shù)的最頂層以及任何 return 之前使用 Hook
這有助于React在多個(gè)useState
和useEffect
調(diào)用之間保留鉤子的狀態(tài)。
翻譯原文鏈接:bobbyhadz.com/blog/react-…
以上就是解決React報(bào)錯(cuò)Rendered more hooks than during the previous render的詳細(xì)內(nèi)容,更多關(guān)于React報(bào)錯(cuò)Rendered more hooks的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React利用路由實(shí)現(xiàn)登錄界面的跳轉(zhuǎn)
這篇文章主要介紹了React利用路由實(shí)現(xiàn)登錄界面的跳轉(zhuǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04淺談React?Refs?使用場(chǎng)景及核心要點(diǎn)
本文主要介紹了React?Refs?使用場(chǎng)景及核心要點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06React循環(huán)遍歷渲染數(shù)組和對(duì)象元素方式
這篇文章主要介紹了React循環(huán)遍歷渲染數(shù)組和對(duì)象元素方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09react中實(shí)現(xiàn)搜索結(jié)果中關(guān)鍵詞高亮顯示
這篇文章主要介紹了react中實(shí)現(xiàn)搜索結(jié)果中關(guān)鍵詞高亮顯示,使用react實(shí)現(xiàn)要比js簡(jiǎn)單很多,方法都是大同小異,具體實(shí)現(xiàn)代碼大家跟隨腳本之家小編一起看看吧2018-07-07阿里低代碼框架lowcode-engine自定義設(shè)置器詳解
這篇文章主要為大家介紹了阿里低代碼框架lowcode-engine自定義設(shè)置器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02React?Hook?Form?優(yōu)雅處理表單使用指南
這篇文章主要為大家介紹了React?Hook?Form?優(yōu)雅處理表單使用指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03React.js組件實(shí)現(xiàn)拖拽排序組件功能過(guò)程解析
這篇文章主要介紹了React.js組件實(shí)現(xiàn)拖拽排序組件功能過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04