解決React報錯Rendered more hooks than during the previous render
總覽
當我們有條件地調用一個鉤子或在所有鉤子運行之前提前返回時,會產(chǎn)生"Rendered more hooks than during the previous render"錯誤。為了解決該錯誤,將所有的鉤子移到函數(shù)組件的頂層,以及不要在條件中使用鉤子。

這里有個示例用來展示錯誤是如何發(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>
);
}
代碼的問題在于,我們有條件地調用了useEffect鉤子。
頂層調用
為了解決該錯誤,我們必須將條件移到鉤子內(nèi)部。因為React鉤子只能在頂層調用。
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語句移動到了useEffect鉤子內(nèi)部。
這就解決了錯誤,因為我們必須確保每次組件渲染時,React鉤子都以相同的順序被調用。
這意味著我們不允許在循環(huán)、條件或嵌套函數(shù)中使用鉤子。
這里有另外一個示例用來展示錯誤是如何發(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>
);
}
問題在于,第二個useState鉤子只有在上面的條件沒有滿足時才會被調用。
條件之上
為了解決這個錯誤,把所有的鉤子移到組件的頂層,在任何可能返回值的條件之上。
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>
);
}
我們把第二個useState鉤子移動到有可能返回一個值的if條件上面。
這是很有幫助的,因為鉤子現(xiàn)在在頂層,并且有可預測的行為,允許React在調用useState和useEffect之間正確地保存狀態(tài)。
就像文檔中所說的那樣:
- 只從React函數(shù)組件或自定義鉤子中調用Hook
- 只在最頂層使用 Hook
- 不要在循環(huán),條件或嵌套函數(shù)中調用 Hook
- 確保總是在你的 React 函數(shù)的最頂層以及任何 return 之前使用 Hook
這有助于React在多個useState和useEffect調用之間保留鉤子的狀態(tài)。
翻譯原文鏈接:bobbyhadz.com/blog/react-…
以上就是解決React報錯Rendered more hooks than during the previous render的詳細內(nèi)容,更多關于React報錯Rendered more hooks的資料請關注腳本之家其它相關文章!
相關文章
React Native:react-native-code-push報錯的解決
這篇文章主要介紹了React Native:react-native-code-push報錯的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

