react 中 useEffect Hook 作用

news/2024/11/16 20:59:07 标签: javascript, 前端, react.js

`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(() => {

    // 模拟在组件挂载后获取数据,相当于componentDidMount

    fetch("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变化时,重新获取数据,类似于componentDidUpdate

    if (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 () => {

      // 组件卸载或依赖项变化时清除定时器,相当于componentWillUnmount

      clearInterval(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.niftyadmin.cn/n/5754613.html

相关文章

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型&#xff08;E-R数据模型&#xff09;被开发来方便数据库的设计&#xff0c;它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…

如何把本地docker 镜像下载用到centos系统中呢?

如果需要将镜像下载到本地或在 CentOS 系统上使用该镜像&#xff0c;你可以按照以下步骤操作&#xff1a; 1. 拉取镜像 如果想将镜像从 Docker Hub 或其他镜像仓库下载到本地&#xff0c;可以使用 docker pull 命令。 如果使用的是本地构建的镜像&#xff08;如 isc:v1.0.0&…

MySQL5.7.37安装配置

1.下载MySQL软件包并解压 2.配置环境变量 3.新建my.ini文件并输入信息 [mysqld] #端口号 port 3306 #mysql-5.7.27-winx64的路径 basedirC:\mysql-5.7.37\mysql-5.7.37-winx64 #mysql-5.7.27-winx64的路径\data datadirC:\mysql-5.7.37\mysql-5.7.37-winx64\data #最大连接数…

IDC 报告:百度智能云 VectorDB 优势数量 TOP 1

近日&#xff0c;IDC 发布了《RAG 与向量数据库市场前景预测》报告&#xff0c;深入剖析了检索增强生成&#xff08;RAG&#xff09;技术和向量数据库市场的发展趋势。报告不仅绘制了 RAG 技术的发展蓝图&#xff0c;还评估了市场上的主要厂商。在这一评估中&#xff0c;百度智…

HMSC联合物种分布模型在群落生态学中的贝叶斯统计分析

联合物种分布模型&#xff08;Joint Species Distribution Modelling&#xff0c;JSDM&#xff09;在生态学领域&#xff0c;特别是群落生态学中发展最为迅速&#xff0c;它在分析和解读群落生态数据的革命性和独特视角使其受到广大国内外学者的关注。在学界不同研究团队研发出…

Qt文件目录操作

文件目录操作相关类 Qt 为文件和目录操作提供了一些类&#xff0c;利用这些类可以方便地实现一些操作。Qt 提供的与文件和目录操作相关的类包括以下几个&#xff1a; QCoreApplication&#xff1a;用于提取应用程序路径&#xff0c;程序名等文件信息&#xff1b;QFile&#x…

直接映射缓存配置

对于一个直接映射&#xff08;Direct-Mapped&#xff09;缓存&#xff0c;其缓存总大小为16字节&#xff0c;而每条cache line的大小为4字节&#xff0c;可以理解为以下几个方面&#xff1a; 1. 缓存结构 缓存大小&#xff08;Cache Size&#xff09;&#xff1a;整个缓存空间…

windbg的线程信息dt命令

文章目录 dt命令dt-r 递归全局和局部变量 dt命令 WinDbg 调试器中 dt&#xff08;Display Type&#xff09;命令&#xff0c;它显示了 Windows 中线程环境块&#xff08;Thread Environment Block&#xff0c;简称 TEB&#xff09;的结构。TEB 是一个重要的数据结构&#xff0…