react的严格模式和解决react useEffect执行两次问题

 更新时间:2025年01月24日 11:05:21   作者:满脑子技术的前端工程师  
文章总结:本文详细探讨了React中useEffect执行两次的问题,主要归因于React的严格模式,严格模式在开发模式下会故意重复调用一些生命周期方法,以帮助开发者发现潜在的问题,包括不安全的生命周期、过时的ref API、废弃的findDOMNode方法、意外的副作用等

useEffect执行两次

这个问题,主要是刚接触react的时候发的问题,当时也没总结。现在回过头来再总结一次!!!

能发现这个问题的,一定是一名细心并且有一颗求知的心。

因为我当时接触React的时候就是这样的想法。为什么会触发两次?按照正常的声明周期应该执行一次的!!!!!

为什么useEffect执行两次

1.React的严格模式(模版创建项目)

  • npx create-react-app my-app 创建React项目
  • npx create-react-app my-app --template typescript 创建typeScript模版的React项目

2.React的严格模式(StrictMode包裹显渲染组件)

root.render(
  //就是下面的代码 React.StrictMode
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

3.React的严格模式作用

StrictMode 是一个用来突出显示应用程序中潜在问题的工具。StrictMode 不会渲染任何可见的 UI。StrictMode 为其后代元素触发额外的检查和警告。

⚠️严格模式检查仅在开发模式下运行;它们不会影响生产构建。 开发发挥作用、线上会自动屏蔽【StrictMode】

作用1:识别不安全的生命周期

React开发中使用严格模式的作用主要是为了识别 Class组件中一些逐渐废弃的组件生命周期,还有引用的第三方组件库中的一些生命周期方法。

React中使用严格模式,一旦发现有风险的生命周期的使用就会在控制台中提出警告

作用2:关于使用过时字符串 ref API 的警告

refs为字符串的危害⚠️

如下图:

作用3:关于使用废弃的 findDOMNode 方法的警告

findDOMNode 也可用于 class组件,但它违反了抽象原则,它使得父组件需要单独渲染子组件。

它会产生重构危险,你不能更改组件的实现细节,因为父组件可能正在访问它的 DOM节点。

findDOMNode 只返回第一个子节点,但是使用 Fragments,组件可以渲染多个 DOM 节点。findDOMNode是一个只读一次的 API。

调用该方法只会返回第一次查询的结果。如果子组件渲染了不同的节点,则无法跟踪此更改。因此,findDOMNode仅在组件返回单个且不可变的 DOM 节点时才有效。

作用4:检测意外的副作用(useEffect副作用)

1.React的工作阶段

  • React 分两个阶段工作:
  • 渲染阶段: 会确定需要进行哪些更改,比如 DOM。在此阶段,React 调用 render,然后将结果与上次渲染的结果进行比较。
  • 提交阶段: 发生在当 React 应用变化时。(对于 React DOM 来说,会发生在 React 插入,更新及删除 DOM 节点的时候。)在此阶段,React 还会调用 componentDidMount 和 componentDidUpdate 之类的生命周期方法。

2.React严格模式的重复调用

严格模式不能自动检测到你的副作用,但它可以帮助你发现它们。

通过故意重复调用以下函数来实现的该操作:

  • class 组件的constructorrendershouldComponentUpdate
  • 组件的生命周期方法:getDerivedStateFromProps
  • 函数组件通过使用 useStateuseMemo或者useReducer

3.Tips:

严格模式采用故意重复调用方法(如组件的构造函数)的方式,使得这种 bug 更容易被发现。

作用5:检测过时的 context API

过时的 context API 容易出错,将在未来的主要版本中删除。

在所有 16.x 版本中它仍然有效,但在严格模式下,将显示以下警告:

解决useEffect执行两次(删除严格模式)

代码如下:

  //就是下面的代码 React.StrictMode
  // <React.StrictMode>
    <App />
  // </React.StrictMode>

图片如下:

关闭严格模式前,如下图:

关闭严格模式后,如下图:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • React中updateContainerImpl方法更新容器源码解析

    React中updateContainerImpl方法更新容器源码解析

    updateContainerImpl方法是React中更新容器的核心方法,负责创建和调度更新,通过createUpdate方法创建更新对象,并通过enqueueUpdate方法将其加入Fiber节点的更新队列,本文介绍React中updateContainerImpl方法更新容器源码分析,感兴趣的朋友一起看看吧
    2026-01-01
  • ant中select回显value问题及解决

    ant中select回显value问题及解决

    在React项目中使用Ant Design的Select组件时,如果设置了自定义的`fieldNames`属性,选中项的label会显示,但回填到选择框时显示的是value值,解决方法是使用`optionLabelProp`属性指定回填到选择框的Option属性为自定义的label字段
    2026-03-03
  • React Router V6更新内容详解

    React Router V6更新内容详解

    这篇文章主要为大家介绍了React Router V6更新内容,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • 使用webpack搭建react开发环境的方法

    使用webpack搭建react开发环境的方法

    本篇文章主要介绍了使用webpack搭建react开发环境的方法,在这篇文章中我们开始利用我们之前所学搭建一个简易的React开发环境,用以巩固我们之前学习的Webpack知识。一起跟随小编过来看看吧
    2018-05-05
  • React状态提升案例介绍

    React状态提升案例介绍

    这篇文章主要介绍了React状态提升案例,所谓 状态提升 就是将各个子组件的 公共state 提升到它们的父组件进行统一存储、处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-04-04
  • React Native仿美团下拉菜单的实例代码

    React Native仿美团下拉菜单的实例代码

    本篇文章主要介绍了React Native仿美团下拉菜单的实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • React项目中decorators装饰器报错问题解决方案

    React项目中decorators装饰器报错问题解决方案

    这篇文章主要介绍了React项目中decorators装饰器报错,本文给大家分享问题所在原因及解决方案,通过图文实例相结合给大家介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • React实现多个场景下鼠标跟随提示框详解

    React实现多个场景下鼠标跟随提示框详解

    这篇文章主要为大家介绍了React实现多个场景下鼠标跟随提示框详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • React服务端渲染原理解析与实践

    React服务端渲染原理解析与实践

    这篇文章主要介绍了React服务端渲染原理解析与实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • React中swiper的配置(reactjs-swiper)

    React中swiper的配置(reactjs-swiper)

    本文详述了在React项目中使用reactjs-swiper组件的步骤与技巧,包括安装、配置、解决swiperOptions无效问题及组件挂载,下面就来详细的介绍一下
    2026-06-06

最新评论