ReactHooks:useEffect使用指南

useEffect 基本使用

useEffect 根据传参个数和传参格式,它的执行次数和执行结果是不同的。

useEffect(setup, dependencies?)

  • 在没有依赖项数组时,每次渲染之后都会执行 Effect
  • 依赖项数组可以设置多个依赖项,其中任意一项发生变化,Effect 都会执行

需要注意的是:

当依赖项是引用类型时,React 会比较依赖项的内存地址是否一样,如果一致,Effect 不会执行。示例如下:

import React, { useState, useEffect } from "react";const Child = ({ data }) => {useEffect(() => {console.log("useEffect");}, [data]);return <div>{data.x}</div>;
};let data = { x: 0 };
const App = () => {const [count, setCount] = useState(0);console.log("render");return (<div><buttononClick={() => {data.x = data.x + 1;setCount(count + 1);}}>click</button><Child data={data} /></div>);
};export default App;

点击 click 之后,对象 data 中的属性值会发生变化,但是传入组件 <Child /> 组件的内存地址没有变化,所以 console.log(“useEffect”) 不会执行。为解决这个问题,应该使用对象中的属性作为依赖,而不是整个对象。应该将上面示例中组件 <Child /> 修改如下:

const Child = ({ data }) => {useEffect(() => {console.log("useEffect");}, [data.x]);return <div>{data.x}</div>;
};

useEffect 的执行时机和 useLayoutEffect

useEffect在渲染完成后异步执行,不会阻塞浏览器的绘制操作。

然而并非所有的操作都适合放在 useEffect 中延迟执行。例如:在浏览器下一次绘制之前需要操作 DOM 改变页面样式,或者依赖布局信息渲染组件。如果放在 useEffect 中执行,会出现闪屏问题。而 useLayoutEffect 在浏览器执行绘制之前被同步执行,使用 useLayoutEffect 可以避免这个问题。

准确绑定依赖

const Example = () => {const [count, setCount] = useState(0);useEffect(() => {console.log("useEffect");const timer = setInterval(() => {console.log("setInterval");setCount(count + 1);}, 1000)return () => clearInterval(timer);}, [])return <p> {count} </p>;
}

在上面例子中,useEffect 用到的依赖项 count,却没有声明在依赖项中,useEffect 不会重复执行(只在组件挂载时打印了一次 useEffect),setInterval 中拿到的 count 始终为 0,它后面每一秒都会调用 setCount(0 + 1),得到的结果始终为 1。下面是两种可以正确解决依赖的方法:

1. 在依赖项数组中包含所有在 Effect 中用到的值

将 Effect 中用到的外部变量 count 添加到依赖项数组中:

useEffect(() => {console.log("useEffect");const timer = setInterval(() => {setCount(count + 1);}, 1000)return () => {console.log(`return${count}`);clearInterval(timer);}
}, [count])

可以看出依赖项数组是正确的,并且解决了上面的问题。但是也可以发现,随之带来的问题是:定时器会在每一次 count 改变后销毁和重新创建,这并不是我们想要的结果。

2. 第二种方法是修改 Effect 中的代码来减少依赖项

useEffect(() => {console.log("useEffect");const timer = setInterval(() => {setCount((count) => count + 1);}, 1000)return () => {console.log('return');clearInterval(timer);}
}, [])

修改 Effect 内部的代码使 useEffect 的依赖更少,这需要一些移除依赖常用的技巧。如:setCount 还有一种函数回调模式,这种模式不需要关心当前值是什么,只需要对 “旧的值” 进行修改即可。这样就不需要把 count 写进依赖项数组这种方式来告诉 React。

是否需要清除副作用

如果只是在 React 更新 DOM 之后运行一些额外的代码,如发送网络请求等,则无需清除操作。

需要清除的是那些执行之后还有后续的操作,如定时器或者页面的监听事件等。为防止内存泄漏,可以通过 useEffect 的 return 销毁通过 useEffect 注册的监听。

const Example = () => {const [count, setCount] = useState(0);useEffect(() => {console.log("useEffect");return () => {console.log("return");}}, [count])return (<div><p> {count} </p>{console.log("dom")}<button onClick={() => setCount(count + 1)}>click</button></div>)
} 

从 dom、return、useEffect 的打印结果可以看出,useEffect 的清除函数在每次重新渲染时都会执行,而不是只在组件卸载时执行。清除函数是在新的渲染之后执行的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/617802.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE5 简易MC教程学习心得

https://www.bilibili.com/video/BV12G411J7hV?p13&spm_id_frompageDriver&vd_sourceab35b4ab4f3968642ce6c3f773f85138 ———— 目录 0.摧毁逻辑学习 1.发光材质灯方块 2.封装。想让子类 不更改父类的变量。 3.材质命名习惯。 0.摧毁逻辑学习 达到摧毁的条件…

用模方软件进行模型的透明贴图,为什么翻出来透明部分是黑的?

答&#xff1a;透贴需要用PNG格式。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.1新增自动单体化建模功能&#xff0c;支持一键自动提取房屋结构&#xff0c;平均1栋复杂建筑物只需3…

JAVA毕业设计121—基于Java+Springboot的房屋租赁管理系统(源代码+数据库+9000字文档)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringboot的房屋租赁管理系统(源代码数据库9000字文档)121 一、系统介绍 本项目还有ssm版本&#xff0c;分为用户、房东、管理员三种角色 1、用户&#xff1a; 注册、登…

【机器学习300问】5、什么是强化学习?

我将从三个方面为大家简明阐述什么是强化学习&#xff0c;首先从强化学习的定义大家的了解强化学习的特点&#xff0c;其次学习强化学习里特殊的术语加深对强化学习的理解&#xff0c;最后通过和监督学习与无监督学习的比较&#xff0c;通过对比学习来了解强化学习。 一、强化…

thinkphp6报错Driver [Think] not supported.

thinkphp6报错Driver [Think] not supported. 问题解决方法测试 问题 直接使用 View::fetch();渲染模板报错 解决方法 这个报错是由于有安装视图驱动造成的 运行如下命令安装即可 composer require topthink/think-view官方文档中是这么写的 视图功能由\think\View类配合视…

JavaScript基础03

1 - 循环 1.1 for循环 语法结构 for(初始化变量; 条件表达式; 操作表达式 ){//循环体 } 名称作用初始化变量通常被用于初始化一个计数器&#xff0c;该表达式可以使用 var 关键字声明新的变量&#xff0c;这个变量帮我们来记录次数。条件表达式用于确定每一次循环是否能被执行…

Python元组(tuple)

目录 元组元组的创建和删除访问元组元素修改元组元组方法 元组 元组是有序且不可更改的集合。在 Python 中&#xff0c;元组是用圆括号编写的。 元组的创建和删除 实例 创建元组&#xff1a; thistuple ("a", "b", "c") print(thistuple)删除…

redis夯实之路-哨兵(Sentinel)机制详解

Sentinel&#xff08;哨兵&#xff09;保证了redis的高可用性&#xff0c;一个Sentinel或多个Sentinel组成的系统监视多个主从服务器&#xff0c;当主服务器下线时&#xff0c;自动将一个从服务器升级为主服务器。 sentinel的主要功能 集群监控&#xff1a;负责监控redis mas…

Nightingale 夜莺监控系统 - 监控篇(2)

Author&#xff1a;rab 官方文档&#xff1a;https://flashcat.cloud/docs/content/flashcat-monitor/categraf/3-configuration/ 目录 前言一、Categraf 配置文件二、Input 插件配置文件2.1 插件说明2.2 通用配置2.2.1 配置采集频率 interval2.2.2 配置采集实例 instances2.2…

word写标书的疑难杂症总结

最近在解决方案工作&#xff0c;与office工具经常打交道&#xff0c;各种问题&#xff0c;在此最下记录&#xff1a; 1.word中文档距离文档顶端有距离调整不了 1.疑难杂症问题1&#xff0c;多个空格都是不能解决 #解决办法&#xff1a;word中--布局-下拉框---“版式”--“垂直…

css3基础语法与盒模型

css3基础语法与盒模型 前言CSS3基础入门css3的书写位置内嵌式外链式导入式&#xff08;工作中几乎不用&#xff09;行内式 css3基本语法css3选择器标签选择器id选择器class类名原子类复合选择器伪类元素关系选择器序号选择器属性选择器css3新增伪类![在这里插入图片描述](https…

canvas设置渐变色文字(线性、径向)

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

gitee完整使用教程,创建项目并上传

目录 一 什么是gitee 二 安装Git 三 登录gitee&#xff0c;生成密钥 四 配置SSH密钥 五 创建项目 六 克隆仓库到本地 七 关联本地工程到远程仓库 八 添加文件 九 异常处理 十 删除仓储 十一 git常用命令 一 什么是gitee gitee是开源中国推出的基于git的代码托管服务…

Sqoop性能优化:高效数据传输的技巧

当使用Apache Sqoop进行数据传输时&#xff0c;性能优化至关重要。高效的数据传输可以减少任务运行时间&#xff0c;减轻集群负载&#xff0c;提高整体工作效率。在本文中&#xff0c;将深入探讨Sqoop性能优化的关键技巧&#xff0c;并提供丰富的示例代码&#xff0c;以帮助大家…

response.cookies详解

response.cookies详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同深入探讨在Web开发中不可或缺的一项知识——“response.cookies”&…

短视频账号矩阵剪辑分发系统技术源头开发

1.技术开发必备的开发文档说明&#xff1a; 1.1系统架构&#xff1a; 抖音SEO排名系统主要由以下几个模块组成&#xff1a; 1. 数据采集模块&#xff1a;负责采集抖音上的相关数据&#xff0c;包括视频、用户、话题等。 2. 数据处理模块&#xff1a;对采集到的数据进行处理&a…

使用斐波那契(Fibonacci)数列来测试各大语言的性能

笔者使用最多的语言是C&#xff0c;目前项目中在使用Go&#xff0c;也使用过不少其它语言&#xff0c;像Erlang&#xff0c;Python&#xff0c;Lua&#xff0c;C#等等。最近看到C#夺冠&#xff0c;首次荣获 TIOBE 年度编程语言&#xff0c;同时也看到网上有不少Java与C#之争的文…

【机器学习300问】4、机器学习到底在学习什么?

首先我们先了解一个前置问题&#xff0c;再回答机器学习到底在学习什么。 一、求机器学习问题有哪几步&#xff1f; 求解机器学习问题的步骤可以分为“学习”和“推理”两个阶段。首先&#xff0c;在学习阶段进行模型的学习&#xff0c;然后&#xff0c;在推理阶段用学到的模型…

C++ STL中的 pair

pair 概述 pair 用于将两个可能是不同数据类型的值结合在一起。pair 提供了一种将两个异构对象存储为单个单元的方法。如果想存储元组&#xff0c;基本上会使用它。pair 容器是一个定义在 <utility> 头文件中的简单容器&#xff0c;由两个数据元素或对象组成。 第一个元…

匠心科技BLDC开发板原理图讲解

匠心科技BLDC开发板资料 链接&#xff1a;https://pan.baidu.com/s/1s5YjzRSDLKQvl86lBVAqKA?pwda6cx 提取码&#xff1a;a6cx 解压密码&#xff1a;JXKJ_RALDNWB站视频讲解&#xff08;&#xff09; 链接: 匠心科技直流无刷电机开发板原理图讲解 BLDC的开发板主要分为四个模…