React Error:Rendered more hooks than during the previous render

2,307 阅读1分钟

错误信息原文

Error: Rendered more hooks than during the previous render. 

报错原因

  1. 有条件的 调用一个 hook
  2. 在所有 hook 运行之间就 return 了

错误示范:有条件的调用 hook 导致的

import { useEffect, useState } from 'react'

const App = () => {
    const [counter, se] = useState(0)
    
    // Error: Rendered more hooks than during the previous render
    if(counter > 0){
        // calling React hook conditionally
        useEffect( () => {
                console.log('Hello world!')
            }
        )
    }
    
    return <>...</>

}

export default App

解决办法:顶层调用避免出现有条件的使用钩子

顶层调用:将条件置于 hook 内部

将 if 语句移动到 useEffect 内部去使用,确保每一次组件渲染的时,React 钩子都是相同的顺序被调用的


import { useEffect, useState } from 'react'

const App = () => {
    const [counter, se] = useState(0)
    
-    // Error: Rendered more hooks than during the previous render
-    if(counter > 0){
-        // calling React hook conditionally
-        useEffect( () => {
-                console.log('Hello world!')
-            }
-        )
-    }

+    useEffect( () => {
+        if(counter > 0) {
+            console.log('Hello world')
+        }
+    )
    
    return <>...</>

}

export default App

错误示范:在所有钩子调用之前 return

import { useState } from 'react'

const App = () => {
    const [counter, setCounter] = useState(0)
    if(counter > 0) {
        // this returns before second hook runs if condition is met
        return <>....</>
    }
    
    
    // Error beacuse hook is called conditional
    const [color, setColor] = useState('blue')
    
    return <>....</> 
}

exprort default App

解决办法:将所有钩子移动到组件的顶部,在任何可能返回值的条件之上


import { useState } from 'react'

const App = () => {
    const [counter, setCounter] = useState(0)    
+    const [color, setColor] = useState('blue')

    if(counter > 0) {
        return <>....</>
    }
    
-    const [color, setColor] = useState('blue')
    
    return <>....</> 
}

exprort default App

React 编码注意事项

  1. 只在 React 函数组件或者自定义钩子中调用 hook
  2. 只在顶层使用 hook
  3. 不在循环、条件、嵌套函数中使用钩子
  4. 确保总是 在顶层 或者 任何 return 之前 使用钩子