解决React报错Rendered more hooks than during the previous render

 更新时间:2022年12月02日 09:07:10   作者:Borislav Hadzhiev  
这篇文章主要为大家介绍了React报错Rendered more hooks than during the previous render解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

总览

当我们有条件地调用一个钩子或在所有钩子运行之前提前返回时,会产生"Rendered more hooks than during the previous render"错误。为了解决该错误,将所有的钩子移到函数组件的顶层,以及不要在条件中使用钩子。

这里有个示例用来展示错误是如何发生的。

// 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钩子。

顶层调用

为了解决该错误,我们必须将条件移到钩子内部。因为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钩子内部。

这就解决了错误,因为我们必须确保每次组件渲染时,React钩子都以相同的顺序被调用。

这意味着我们不允许在循环、条件或嵌套函数中使用钩子。

这里有另外一个示例用来展示错误是如何发生的。

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条件上面。

这是很有帮助的,因为钩子现在在顶层,并且有可预测的行为,允许React在调用useStateuseEffect之间正确地保存状态。

就像文档中所说的那样:

  • 只从React函数组件或自定义钩子中调用Hook
  • 只在最顶层使用 Hook
  • 不要在循环,条件或嵌套函数中调用 Hook
  • 确保总是在你的 React 函数的最顶层以及任何 return 之前使用 Hook

这有助于React在多个useStateuseEffect调用之间保留钩子的状态。

翻译原文链接:bobbyhadz.com/blog/react-…

以上就是解决React报错Rendered more hooks than during the previous render的详细内容,更多关于React报错Rendered more hooks的资料请关注脚本之家其它相关文章!

相关文章

  • 使用react实现手机号的数据同步显示功能的示例代码

    使用react实现手机号的数据同步显示功能的示例代码

    本篇文章主要介绍了使用react实现手机号的数据同步显示功能的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • React中使用Mobx的方法

    React中使用Mobx的方法

    Mobx是一个前端“状态管理框架”,状态管理就是将分布在各个组件、各个模块中的状态的变化,按照一定的规则,进行统一的管理,这篇文章主要介绍了React中如何使用Mobx,需要的朋友可以参考下
    2023-02-02
  • react高阶组件添加和删除props

    react高阶组件添加和删除props

    这篇文章主要介绍了react高阶组件添加和删除props,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • react 中 mobx的使用案例详解

    react 中 mobx的使用案例详解

    这篇文章主要介绍了react 中 mobx的使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • 使用react-dnd编写一个可拖拽排列的list

    使用react-dnd编写一个可拖拽排列的list

    这篇文章主要为大家详细介绍了如何使用react-dnd编写一个可拖拽排列的list,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • 详解在create-react-app使用less与antd按需加载

    详解在create-react-app使用less与antd按需加载

    这篇文章主要介绍了详解在create-react-app使用less与antd按需加载,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • react如何利用useRef、forwardRef、useImperativeHandle获取并处理dom

    react如何利用useRef、forwardRef、useImperativeHandle获取并处理dom

    这篇文章主要介绍了react如何利用useRef、forwardRef、useImperativeHandle获取并处理dom,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-10-10
  • React 首页加载慢问题性能优化案例详解

    React 首页加载慢问题性能优化案例详解

    这篇文章主要介绍了React 首页加载慢问题性能优化案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • React SSG实现Demo详解

    React SSG实现Demo详解

    这篇文章主要为大家介绍了React SSG实现Demo详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-07-07
  • 详解React 16 中的异常处理

    详解React 16 中的异常处理

    这篇文章主要介绍了详解React 16 中的异常处理的相关资料,React 16.x 版本中,引入了所谓 Error Boundary 的概念,从而保证了发生在 UI 层的错误不会连锁导致整个应用程序崩溃;未被任何异常边界捕获的异常可能会导致整个 React 组件树被卸载,需要的朋友可以参考下
    2017-07-07

最新评论