react 中 useEffect Hook 作用

embedded/2024/11/17 3:32:13/

`useEffect`是一个用于处理副作用(Side Effects)的 Hook

一、处理副作用

1. 副作用的概念

副作用是指在组件渲染过程中执行的、会影响组件外部环境或具有外部可见影响的操作。

常见的副作用包括数据获取(如从服务器获取数据)、订阅外部数据源(如消息队列、事件总线)、手动操作 DOM(如修改页面标题、滚动位置)以及设置定时器等。

2. useEffect 基本用法

2.1 语法结构

`useEffect`接受两个参数,第一个参数是一个函数,称为副作用函数(Effect Function),在这个函数内部执行实际的副作用操作。第二个参数是一个可选的依赖项数组(Dependency Array)。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {// 这是一个副作用函数,这里模拟从服务器获取数据console.log("Fetching data...");return () => {// 可选的清理函数,用于在组件卸载或依赖项变化时清理副作用console.log("Cleaning up...");};}, []);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;

在这个例子中,副作用函数在组件挂载时执行,因为依赖项数组为空(`[]`),表示这个副作用只在组件初始化时触发一次。副作用函数还返回了一个清理函数,用于在组件卸载或依赖项变化时执行清理操作。

二、模拟生命周期方法

1. 替代 componentDidMount

在类组件中,`componentDidMount`方法在组件挂载到 DOM 后立即执行。在函数组件中,可以使用`useEffect`来实现类似的功能。当`useEffect`的依赖项数组为空时,副作用函数在组件第一次渲染(挂载)后执行,相当于`componentDidMount`。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [data, setData] = useState(null);useEffect(() => {// 模拟在组件挂载后获取数据,相当于componentDidMountfetch("https://example.com/api/data").then((response) => response.json()).then((jsonData) => setData(jsonData));}, []);return <div>{data ? <p>{data}</p> : <p>Loading...</p>}</div>;};export default MyComponent;

2. 替代 componentDidUpdate

在类组件中,`componentDidUpdate`方法在组件每次更新(`state`或`props`变化)后执行。在函数组件中,可以通过在`useEffect`的依赖项数组中指定依赖项来模拟`componentDidUpdate`。当依赖项发生变化时,副作用函数会重新执行,类似于`componentDidUpdate`。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);const [data, setData] = useState(null);useEffect(() => {// 当count变化时,重新获取数据,类似于componentDidUpdateif (count > 0) {fetch("https://example.com/api/data").then((response) => response.json()).then((jsonData) => setData(jsonData));}}, [count]);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button>{data ? <p>{data}</p> : <p>Loading...</p>}</div>);};export default MyComponent;

3. 替代 componentWillUnmount

在类组件中,`componentWillUnmount`方法在组件卸载前执行,用于清理资源。在函数组件中,`useEffect`的副作用函数返回的清理函数在组件卸载或依赖项变化时执行,从而替代了`componentWillUnmount`的功能。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {const timer = setInterval(() => {setCount(count + 1);}, 1000);return () => {// 组件卸载或依赖项变化时清除定时器,相当于componentWillUnmountclearInterval(timer);};}, []);return (<div><p>Count: {count}</p></div>);};export default MyComponent;

三、依赖项管理和优化

1. 依赖项的作用

1.1 决定副作用执行时机

例如:如果一个副作用函数依赖于组件的某个状态值,将这个状态值放入依赖项数组中,那么当这个状态值改变时,副作用函数就会重新运行。这样可以确保副作用与组件的状态和属性保持同步。

2. 优化性能

例如:在不必要的时候重复获取数据或重新订阅事件,浪费资源并可能导致应用程序性能下降。

3. 优化策略和常见错误

3.1 空依赖项数组的优化与风险

例如:初始化数据获取或设置全局事件监听器。但如果在副作用函数中使用了组件的状态或属性,并且没有将它们包含在依赖项数组中,就会导致闭包问题。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {// 错误:没有将count包含在依赖项数组中,导致闭包问题console.log("Count:", count);}, []);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;

3.2 正确指定依赖项

为了避免上述问题,需要将副作用函数中使用的所有组件的状态、属性以及其他外部函数(如果在副作用函数内部调用)都包含在依赖项数组中。

javascript">import React, { useEffect, useState } from "react";const MyComponent = () => {const [count, setCount] = useState(0);useEffect(() => {console.log("Count:", count);}, [count]);return (<div><p>Count: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);};export default MyComponent;


http://www.ppmy.cn/embedded/138161.html

相关文章

tdengine学习笔记

官方文档&#xff1a;用 Docker 快速体验 TDengine | TDengine 文档 | 涛思数据 整体架构 TDENGINE是分布式&#xff0c;高可靠&#xff0c;支持水平扩展的架构设计 TDengine分布式架构的逻辑结构图如下 一个完整的 TDengine 系统是运行在一到多个物理节点上的&#xff0c;包含…

Linux服务器下oracle自动rman备份的实现

一、概述 为确保oracle数据库数据的安全和一致性&#xff0c;一般我们都需要利用备份手段进行数据库的备份。在oracle数据库中&#xff0c;rman因其强大的功能和完善的手段&#xff0c;成为数据库备份的首选。Linux服务器中&#xff0c;要实现自动脚本备份&#xff0c;一般都是…

gitHub常用操作

gitHub常用操作 1、把项目拉下来2、添加上游仓库3、进入分支4、从上游仓库拉取更新 1、把项目拉下来 在对应项目的右上角点击fork&#xff0c;fork下来&#xff1a;将远程仓库复制到个人仓库 在创建好的分支文件夹下使用 git clone自己远程仓库下的http地址&#xff08;fork…

【Linux】Ubuntu中muduo库的编译环境安装

Muduo is a multithreaded C network library based on the reactor pattern. muduo库的介绍就是&#xff1a;一个基于reactor反应堆模型的多线程C网络库。 muduo网络库是C语言开发的一个非常优秀的网络库&#xff0c;作者陈硕&#xff0c;muduo网络库在多线程环境下性能非常高…

c++写一个死锁并且自己解锁

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

【eNSP】企业网络架构实验——vlan间的路由通信(三)

VLAN间的路由是指不同VLAN之间的通信&#xff0c;通常VLAN是用来分割网络流量和提高网络安全性的。 一、VLAN 1. 什么是VLAN&#xff1f; VLAN&#xff0c;全称是虚拟局域网&#xff08;Virtual Local Area Network&#xff09;&#xff0c;是一种将物理局域网&#xff08;LA…

Python爬虫学习路线精简大纲!!!

Python爬虫学习路线精简版&#xff1a; python爬虫最新课程资料&#xff1a;https://kakatu.top/m?sdata 一、基础阶段 Python语言基础&#xff1a;学习Python的基本语法、数据类型、控制结构、函数等&#xff0c;这是编写爬虫脚本的基础。 网页基础知识&#xff1a;了解HTM…

三、计算机视觉_01图像的基本操作

0 前言 图像的读取和处理是计算机视觉领域中的一个基本任务&#xff0c;在Python中&#xff0c;有几个流行的库可以用来读取和处理图像数据 0.1 Matplotlib介绍 Matplotlib是Python中一个非常流行的绘图库&#xff0c;它通常用于数据可视化&#xff0c;虽然它不是专门的图像…