【React】useEffect 钩子详解

Peter-Lu 2024-09-11 12:03:01 阅读 68

文章目录

一、useEffect 概念二、useEffect 的基本用法1. 无依赖项2. 空依赖项数组3. 带依赖项的 useEffect

三、useEffect 的常见应用场景1. 数据获取2. 订阅与清除3. 动画与定时器

四、useEffect 的进阶用法1. 多个 useEffect2. 条件执行副作用

五、注意事项

<code>useEffect 是 React 钩子函数之一,它使函数组件能够执行副作用操作。常见的副作用包括数据获取、订阅、手动更改 React 组件中的 DOM 以及定时器等。在类组件中,我们通常在生命周期方法中执行这些操作,而在函数组件中,我们使用 useEffect 来完成这些任务。本文将详细介绍 useEffect 的概念、用法及其在实际开发中的应用,旨在帮助开发者全面掌握这一重要特性。

一、useEffect 概念

useEffect 钩子是 React 16.8 版本引入的,它允许我们在函数组件中执行副作用操作。useEffect 函数接收两个参数:

一个副作用函数。一个依赖项数组(可选)。

基本语法如下:

useEffect(() => { -- -->

// 副作用逻辑

return () => {

// 清除逻辑(可选)

};

}, [依赖项]);

二、useEffect 的基本用法

1. 无依赖项

如果不传递依赖项数组,副作用函数会在每次渲染后执行。

import React, { useEffect } from 'react';

function MyComponent() {

useEffect(() => {

console.log('组件渲染或更新了');

return () => {

console.log('组件卸载了');

};

});

return <div>Hello, useEffect!</div>;

}

上述代码中,console.log 会在每次组件渲染或更新时执行,而返回的清除函数会在组件卸载时执行。

2. 空依赖项数组

如果传递一个空数组作为依赖项,副作用函数只会在组件首次渲染时执行一次。

import React, { useEffect } from 'react';

function MyComponent() {

useEffect(() => {

console.log('组件首次渲染');

return () => {

console.log('组件卸载');

};

}, []);

return <div>Hello, useEffect!</div>;

}

3. 带依赖项的 useEffect

如果传递一个依赖项数组,副作用函数会在依赖项发生变化时执行。

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

function MyComponent() {

const [count, setCount] = useState(0);

useEffect(() => {

console.log(`Count 发生变化: ${ count}`);

return () => {

console.log(`清除副作用: ${ count}`);

};

}, [count]);

return (

<div>

<p>{ count}</p>

<button onClick={ () => setCount(count + 1)}>增加</button>

</div>

);

}

上述代码中,当 count 发生变化时,副作用函数会执行,同时会先执行上一次渲染中的清除函数。

三、useEffect 的常见应用场景

1. 数据获取

在函数组件中使用 useEffect 可以方便地进行数据获取。

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

function DataFetchingComponent() {

const [data, setData] = useState(null);

useEffect(() => {

fetch('https://api.example.com/data')

.then(response => response.json())

.then(data => setData(data));

// 清除逻辑

return () => {

// 取消请求或其他清除操作

};

}, []); // 空依赖数组表示只在组件挂载和卸载时执行

if (!data) {

return <div>Loading...</div>;

}

return <div>{ JSON.stringify(data)}</div>;

}

2. 订阅与清除

useEffect 也可以用于设置和清除订阅,例如事件监听器或 WebSocket 连接。

import React, { useEffect } from 'react';

function EventListenerComponent() {

useEffect(() => {

const handleResize = () => {

console.log('窗口大小改变');

};

window.addEventListener('resize', handleResize);

// 清除逻辑

return () => {

window.removeEventListener('resize', handleResize);

};

}, []); // 空依赖数组表示只在组件挂载和卸载时执行

return <div>请调整窗口大小查看效果</div>;

}

3. 动画与定时器

我们可以使用 useEffect 来设置和清除定时器或启动动画。

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

function TimerComponent() {

const [count, setCount] = useState(0);

useEffect(() => {

const intervalId = setInterval(() => {

setCount(prevCount => prevCount + 1);

}, 1000);

// 清除逻辑

return () => {

clearInterval(intervalId);

};

}, []); // 空依赖数组表示只在组件挂载和卸载时执行

return <div>计数: { count}</div>;

}

四、useEffect 的进阶用法

1. 多个 useEffect

在一个组件中可以使用多个 useEffect,每个 useEffect 可以负责不同的副作用操作。

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

function MultiEffectComponent() {

const [count, setCount] = useState(0);

const [data, setData] = useState(null);

useEffect(() => {

document.title = `计数: ${ count}`;

}, [count]);

useEffect(() => {

fetch('https://api.example.com/data')

.then(response => response.json())

.then(data => setData(data));

}, []);

return (

<div>

<p>计数: { count}</p>

<button onClick={ () => setCount(count + 1)}>增加</button>

<div>数据: { JSON.stringify(data)}</div>

</div>

);

}

2. 条件执行副作用

通过条件判断,可以有选择地执行副作用逻辑。

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

function ConditionalEffectComponent() {

const [count, setCount] = useState(0);

const [fetchData, setFetchData] = useState(false);

const [data, setData] = useState(null);

useEffect(() => {

if (fetchData) {

fetch('https://api.example.com/data')

.then(response => response.json())

.then(data => setData(data));

}

}, [fetchData]);

return (

<div>

<p>计数: { count}</p>

<button onClick={ () => setCount(count + 1)}>增加</button>

<button onClick={ () => setFetchData(true)}>获取数据</button>

<div>数据: { JSON.stringify(data)}</div>

</div>

);

}

五、注意事项

避免不必要的副作用:确保副作用函数只在需要时执行。使用依赖项数组来控制副作用的执行时机,避免不必要的重复执行。清除副作用:副作用函数返回的清除函数用于清理不再需要的副作用。例如,清除事件监听器、取消订阅或清除定时器等。依赖项数组:准确指定依赖项数组中的变量,确保副作用函数在依赖项发生变化时正确执行。遗漏或误包含依赖项可能导致副作用执行不符合预期。处理异步操作:在处理异步操作时,注意在组件卸载时取消未完成的请求,避免内存泄漏。性能优化:对于性能敏感的操作,确保合理使用 useEffect,避免过度渲染和不必要的副作用执行。

推荐:JavaScript


在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。