React useState 和 useEffect 使用坑点注意总结

React Hook详解 - useState、useEffect、useContext、useRef、自定义hook 在上面的操作中都不用清理的副作用,然而,有些副作用是需要去清理的,不清理会造成异常甚至内存泄漏,比如开启定时器,如果不清理,则会多次开启,从上面可以看到。因为涉及到 state 的状态合并,react 认为当你在事件绑定中操作 state 是非常频繁的,所以为了节约性能 react 会把多次。类似,可以接收一个新的 state 值更新,也可以函数式更新。进行合并为一次,最后在一次性的更新 state,而定时器里面操作 state 是不会把多次合并为一次更新的。返回一个state,以及更新state的函数。 阅读详情

React Hooks 使用注意事项

Area: Hooks
Date: February 10, 2025
Important: 🌟🌟🌟

React Hooks 注意事项

要点:

  • useState 的初始化值 只在第一次渲染时计算,并且这个值不会随着组件重新渲染而更新。
  • useEffect 可能出现死循环,比如处理请求接口时,依赖项绑定对象类型数据,会死循环。


useState 的初始值问题

Case:useState 的初始化值 只在第一次渲染时计算,并且这个值不会随着组件重新渲染时更新。

理解:useState 的初始化值只在组件的第一次渲染时生效,不会随着 props 或 state 的变化而更新。

2025-02-16 23.03.54.gif

import React, { useState } from 'react'

// 子组件
function Child({ userInfo }) {
  // render: 初始化 state
  // re-render: 只恢复初始化的 state 值,不会再重新设置新的值
  //            只能用 setName 修改
  const [name, setName] = useState(userInfo.name)

  return (
    <div>
      <p>Child, props name: {userInfo.name}</p>
      <p>Child, state name: {name}</p>
    </div>
  )
}

function App() {
  const [name, setName] = useState('双越')
  const userInfo = { name }

  return (
    <div>
      <div>
        Parent &nbsp;
        <button onClick={() => setName('慕课网')}>setName</button>
      </div>
      <Child userInfo={userInfo} />
    </div>
  )
}

export default App

解决方案:使用 useEffect 来监听 userInfo 的变化,并在变化时更新 name。

import React, { useState, useEffect } from 'react'

function Child({ userInfo }) {
  const [name, setName] = useState(userInfo.name)

  // 使用 useEffect 来监听 userInfo.name 的变化并更新 name
  useEffect(() => {
    setName(userInfo.name)
  }, [userInfo.name])  // 当 userInfo.name 发生变化时更新 name

  return (
    <div>
      <h1>Child, Props name: {userInfo.name}</h1>
      <h1>Child, state name: {name}</h1>
    </div>
  )
}

function App() {
  const [name, setName] = useState('Nathan')
  const userInfo = {
    name,
  }
  return (
    <div>
      <h1>UserName</h1>
      <button onClick={() => setName('XXXX')}>Change Name</button>
      <Child userInfo={userInfo} />
    </div>
  )
}

export default App



useEffect 的死循环问题

Case:useEffect 死循环

理解:处理请求接口时,依赖项绑定对象类型数据,会死循环。

2025-02-16 23.24.16.gif

import { useState, useEffect } from 'react'
import axios from 'axios'

// 传入 config,类型为对象
function useAxios(url, config = {}) {
  const [loading, setLoading] = useState(false)
  const [data, setData] = useState()
  const [error, setError] = useState()

  useEffect(() => {
    setLoading(true)
    axios
      .get(url) // 发送一个 get 请求
      .then(res => setData(res))
      .catch(err => setError(err))
      .finally(() => setLoading(false))
  }, [url, config])

  return [loading, data, error]
}

export default useAxios

分析:

1-useEffect 和依赖项的关系:

在 useEffect 中,[url, config] 是依赖项数组。这意味着当 url 或 config 发生变化时,useEffect 会重新执行。

2-对象 config 的变化:

在 JavaScript 中,对象(如 config)是引用类型。如果每次重新渲染时,config 的引用发生了变化,即使它的内容相同,React 也会认为它发生了变化,从而触发 useEffect 的重新执行。

这就导致了一个问题:每次组件重新渲染时,config 对象的引用可能会发生变化,即使它的值没有改变。这会导致 useEffect 被反复调用,进而每次发起请求。

注:这里 React 底层使用的是 Object.is() 进行比较

image.png

总结无限请求的原因:

  • 每次组件渲染时,config 会被认为是新的对象(即使它的内容没有变化),从而触发 useEffect 重新执行。
  • useEffect 执行时会发起请求,且请求可能会导致 config 的变化(如果在请求完成后更新了 config,即使没有显式更新也可能影响父组件中的 config)。
  • 因此,useEffect 会再次被触发,导致请求不断发起,形成无限请求的循环。

解决方案:

基础方案:

useEffect 依赖项不要放置对象类型。可在之前将对象解构,useEffect依赖项中放置基本类型值

另一种方案:

如果你希望在 config 变化时也重新发送请求,你可以使用 useMemo 来确保只有在 config 内容变化时才触发请求:

import { useState, useEffect, useMemo } from 'react'
import axios from 'axios'

function useAxios(url, config = {}) {
  const [loading, setLoading] = useState(false)
  const [data, setData] = useState()
  const [error, setError] = useState()

  // 使用 useMemo 来确保 config 引用只有在实际变化时才会更新
  const memoizedConfig = useMemo(() => config, [JSON.stringify(config)])

  useEffect(() => {
    setLoading(true)
    axios
      .get(url, memoizedConfig) // 使用 memoizedConfig 而非原始 config
      .then(res => setData(res))
      .catch(err => setError(err))
      .finally(() => setLoading(false))
  }, [url, memoizedConfig])

  return [loading, data, error]
}

export default useAxios

React-Hooks用法:useState()、useEffect()、useRef() 告别难以理解的Class解决业务逻辑难以拆分的问题使状态逻辑复用变得简单可行函数组件在设计思想上,更加契合React的理念1.需求描述:自定义一个hook函数,实现获取滚动距离Yconst [ y ] = useWindowScroll() y就是滚动到顶部的距离每次都有两次控制台输出是因为:React的StrictMode严格模式,忽略第二个输出即可。import {.................. 阅读详情

相关推荐

保姆级教程:在ROS2 Humble上搞定Livox Mid-360雷达,从IP配置到Rviz点云显示

本文提供在ROS2 Humble上配置Livox Mid-360激光雷达的完整教程,涵盖从IP设置到Rviz点云显示的全流程。详细解析硬件连接、驱动编译、配置文件优化及常见问题排查,帮助开发者快速搭建开发环境并实现高效点云可视化。

weixin_30955617的博客 183

React 里 useEffeft 死循环问题?

在 React 中,useEffect 是一个非常有用的钩子,它允许我们在组件渲染后执行副作用操作。然而,如果不正确使用,可能会导致无限循环的问题。useEffect的第二个参数是一个依赖数组,React 会在这个数组中的任何值改变时重新运行副作用。如果你在 useEffect 中更改了一个依赖,那么就会创建一个无限循环,因为每次运行副作用都会更改依赖,这又会导致重新运行副作用。以下是解决 use...

文摘资讯 1552

第三篇:AMD 和 Intel

它像“乐高积木”一样,可以通过标准化的接口与其他部分组合,构建复杂系统。理解组件后,你会发现从操作系统到微服务,现代软件本质上都是组件的组合!

u013089100的博客 1031

useEffect 无法监控,死循环,第二个参数不能是引用类型

useEffect 无法监控,死循环,第二个参数不能是引用类型

Z_Wonderful的博客 1586

面试中常考的数学题——截木棍、圆上取点、赛马、红蓝墨水,测试毒药、坐到正确座位问题

文章目录1.将一根木棒截成三段,问能够组成三角形的概率;2.在圆上任取三点,问能够组成锐角、直角、钝角三角形的概率;3.共有25匹马,找出最快的3匹,只有5个赛道,每次比赛只能得到5匹马的速度排序,最少需要多少次比赛;4 有两瓶红蓝墨水,体积一样,现在从红墨水中舀一勺加入蓝墨水中,搅拌均匀后,在从蓝墨水中舀一勺加到红墨水中,试问这两瓶墨水哪瓶纯度更高。 1.将一根木棒截成三段,问能够组成三角形的概率; 来源:https://blog.csdn.net/weixin_41245919/article/deta

weixin_41558411的博客 4904

杰理SDK UART 使用教程

本文介绍了JL701n芯片的UART串口通信使用教程,重点讲解了UART2的初始化配置、数据收发和中断处理功能。教程详细说明了代码结构、核心功能函数、配置参数和使用步骤,包括UART初始化、数据发送和接收中断处理等关键操作。同时提供了完整的API接口说明和注意事项,强调了中断处理限制、缓冲区管理、引脚配置等重要细节。最后给出了基本使用流程和高级任务处理示例,并针对常见问题提供了故障排除建议。本教程适用于需要在JL701n芯片上实现可靠串口通信的开发者。

qq_42014563的博客 1818

UseEffect 死循环问题记录

useEffect死循环,是由于在effect中进行了setState, 导致页面重新渲染,重复给依赖复制

学骑扫把的小女巫 5318

【SMPL简介】SMPL: A Skinned Multi-Person Linear Model【源码复现】

SMPL是一种3D人体建模方法.在数字人或者人物角色三维重建领域有着广泛应用支持人体的各种形状及动作可以简单理解为通过训练获取的人物模型SMPL 输入是:姿态shape vectorβ\betaβ+ 影响动作Pose的参数θ\thetaθ输出是: 各种变化后vertex顶点的数据作者:Loper, Matthew and Mahmood, Naureen and Romero, Javier and Pons-Moll, Gerard and Black, Michael J.

zik的博客 3369

React Hooks的坑

React Hooks的坑

ItGoodTime的博客 363

VTK:受约束的 Delaunay 2D用法实战

VTK:受约束的 Delaunay 2D用法实战程序输出程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkCellArray.h> #include <vtkDelaunay2D.h> #include <vtkMath.h> #include <vtkMinimalStandardRandomSequence.h> #include <vtkNamedColors.h>

希望我的博客,能帮上你解决学习中工作中所遇到的问题 944

SKUA-GOCAD入门教程-第二节

软件启动及项目设置

江洋大葱的博客 1146

React-hook 开发踩坑记

React-hook 开发踩坑记 在学习完了 react hook 后,我应用 hook 进行了页面的开发,但是开发中遇到了大大小小的问题,我对一些印象较为深刻的问题做了如下记录。 坑 ×1:修改状态不一定会使页面重新渲染 useState 对状态的判别 首先,关于声明,这里推荐用 const 来声明,也就是如下的声明方式。 const [data, setData] = useState(nul...

qq_46193451的博客 1311

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

终于找到了!Ubuntu 虚拟机卡死的终极解决方案(如何解决VMware安装Ubuntu24.04桌面进不去、黑屏、虚拟机卡死、显示不全、屏幕闪烁等问题)

XiaoqiangClub的博客 1万+

React 18中hook函数详解之useState和useEffect

React 18中hook函数详解之useState和useEffect

任磊 2512

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

React之useState、useEffect原理解析

ReactHooks原理解析

Zong_0915的博客 4628

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Vidact API完全指南:useState、useEffect与其他React钩子实现

Vidact是一个将React兼容代码转换为无虚拟DOM的VanillaJS编译器,让开发者能够使用熟悉的React钩子API编写高效的原生JavaScript应用。本文将全面介绍如何在Vidact中使用useState、useEffect等核心React钩子,帮助你快速上手这个革命性的前端开发工具。 ## 为什么选择Vidact钩子API? Vidact的核心优势在于它允许开发者使用标准的R

gitblog_00207的博客 1039

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

react 之 useState 和 useEffect 应用

react 之 useState 和 useEffect 应用

m0_51244077的博客 832

React——hook之useState,useEffect精讲

React——hook之useState,useEffect精讲

qq_56989560的博客 3114

React基础hooks-useState、useEffect、useRef、useCallback、useContext、useMemo、useReducer等

本文介绍了React Hooks的核心概念和使用方法,主要包括: useState:用于组件状态管理,支持惰性初始化和函数式更新,强调状态不可变性原则。 useEffect:处理副作用(数据获取、订阅等),提供清理机制,通过依赖数组控制执行时机。 useRef:用于访问DOM元素和保存跨渲染周期的可变数据,不会触发重新渲染。 其他核心Hooks: useContext:实现组件树数据共享 useMemo:优化性能,缓存计算结果 useCallback:记忆化回调函数,避免子组件无效渲染 useReducer

m0_51324570的博客 1421

【React-Hooks基础】入门级详解——useState / useEffect /自定义hook

React体系里组件分为 和 经过多年的实战,函数组件是一个更加匹配React的设计理念 ,也更有利于逻辑拆分与重用的组件表达形式,而先前的函数组件是不可以有自己的状态的,为了能让函数组件可以拥有自己的状态,所以从react v16.8开始,Hooks应运而生.注意点:在hooks出现之前,react先后尝试了 mixins混入,HOC高阶组件,render-props等模式 但是都有各自的问题,比如mixin的数据来源不清晰,高阶组件的嵌套问题等等class组件就像一个厚重的‘战舰’ 一样,大而全,提供

xuxuii的博客 2万+

usestate中的回调函数_React Hook之useState、useEffect和useContext

以下文字来自于掘金,已征得作者 hexh授权。前言一周的砖又快搬完了,又到了开心快乐的总结时间~这两周一直在 hook 函数的“坑”里,久久不能自拔。应该也不能叫做“坑”吧,还是自己太菜了,看文档不仔细,很多以为不重要,但在实际应用中却很关键的点总是被自己忽略。所以我准备多花点时间,把官网的一些 hook 函数,再回过头看一遍,整理整理(在整理的过程,我觉得更容易发现问题和总结经验)。这...

weixin_39549852的博客 1159

react学习之useState和useEffect

上面的例子都是setState的操作都是放在具体的方法中,没有直接在函数体中调用。useState 可以使函数组件像类组件一样拥有 state,函数组件通过 useState 可以让组件重新渲染,更新视图。默认情况下,useEffect()中的函数,会在组件渲染完成后调用,并且是每次渲染完成后都会调用。setstate()中回调函数的返回值将会成为新的state值回调函数执行时,当state的值是一个对象时,修改时是使用新的对象去替换已有对象。-setState()会触发组件的重新消染,它是异步的。

Jocelyn_书 806

React:useState和useEffect

最近因为想要开发一个简单的应用才开始接触React。但是并没有系统学习React,所以这篇博客可能会写的不够专业。

读万卷书 行万里路 965

React中的useState 和useEffect

Hook作用重要规则useState让组件记住数据必须用 setXxx 修改状态useEffect处理副作用操作清理函数防止内存泄漏依赖数组控制执行时机。

lzfshub 572

React Hooks核心解析:useState、useEffect与useRef的区别与应用

React Hooks是函数组件开发中的核心技术,其中useState、useEffect和useRef是最基础的三个Hook。useState用于管理组件状态,当状态变化时会触发重新渲染;useEffect处理副作用操作,如数据获取、订阅事件等;useRef则提供了一种持久化存储可变值的方式,且不会触发渲染。理解这三者的区别对于编写高效、可维护的React代码至关重要。在实际开发中,合理使用这些Hook可以避免常见问题如无限循环、内存泄漏等,同时提升应用性能。本文深入解析这三个核心Hook的设计原理、使用

weixin_34152820的博客 432

React Hooks、useState、useEffect 、react函数状态

React 体系里组件分为类组件和函数组件 多年使用发现,函数组件是一个更加匹配 React 的设计理念`UI = f(date)`,也更加有利于逻辑拆分与重用的组件表达形式,而先前组件是不可以有自己的状态的。为了让函数组件可以拥有自己的状态,所以从 react v16.8 开始,加入了 hooks

weixin_53761834的博客 1265
上一篇: React 低代码项目:组件设计
下一篇: React 低代码项目:网络请求与问卷基础实现
CaptainDrake
博客等级 码龄6年 5363粉丝 187原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值