作为一名快6年的前端码农,我可没少和React的useEffect这个家伙打交道。今天我就来聊聊这个让人又爱又恨的Hook,保证让你听得明白,用得顺手!
什么是useEffect?
简单来说,useEffect就是React给我们的一把"瑞士军刀",专门用来处理组件中的副作用操作。什么是副作用?就是那些会影响组件外部世界的操作,比如数据获取、手动修改DOM、设置订阅等等。
想象一下,你正在做菜(组件渲染),但突然需要接个电话(副作用)。useEffect就是那个帮你暂停做菜、接完电话再继续的神奇工具!
基础用法:一看就会
让我来写个简单的例子:
jsx
import { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 这是一个副作用 - 获取数据
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const result = await response.json();
setData(result);
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
fetchData();
}, []); // 空依赖数组表示只在组件挂载时执行
if (loading) return <div>Loading...</div>;
return (
<div>
<h1>My Data</h1>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
依赖数组:控制副作用的执行时机
useEffect的第二个参数是个依赖数组,它决定了副作用什么时候执行:
jsx
// 1. 每次渲染都执行
useEffect(() => {
console.log('我每次渲染都会跑一遍!');
});
// 2. 只在挂载时执行一次
useEffect(() => {
console.log('我只在组件挂载时执行一次');
}, []);
// 3. 依赖变化时执行
useEffect(() => {
console.log('count变化了,我需要重新执行');
}, [count]); // 只在count变化时执行
清理工作:做个负责任的效果
有些副作用需要清理,比如订阅或定时器:
jsx
useEffect(() => {
const timerId = setInterval(() => {
console.log('定时器还在运行...');
}, 1000);
// 返回清理函数
return () => {
clearInterval(timerId);
console.log('定时器已清理');
};
}, []);
实战技巧:我踩过的坑
- 无限循环陷阱
jsx
// 错误示范:这会导致无限重新渲染!
useEffect(() => {
setCount(count + 1);
}, [count]);
// 正确做法:使用函数式更新
useEffect(() => {
setCount(prevCount => prevCount + 1);
}, []); // 不需要依赖count
- 异步处理
jsx
useEffect(() => {
// 正确处理异步操作
let isMounted = true;
const fetchData = async () => {
const result = await someAsyncOperation();
if (isMounted) {
setData(result);
}
};
fetchData();
return () => {
isMounted = false; // 组件卸载时取消操作
};
}, []);
总结
useEffect是React函数组件的核心Hook之一,掌握它能让你:
- 优雅地处理副作用
- 避免内存泄漏
- 写出更清晰、更易维护的代码
⭐ 写在最后
请大家不吝赐教,在下方评论或者私信我,十分感谢🙏🙏🙏.
✅ 认为我某个部分的设计过于繁琐,有更加简单或者更高逼格的封装方式
✅ 认为我部分代码过于老旧,可以提供新的API或最新语法
✅ 对于文章中部分内容不理解
✅ 解答我文章中一些疑问
✅ 认为某些交互,功能需要优化,发现BUG
✅ 想要添加新功能,对于整体的设计,外观有更好的建议
✅ 一起探讨技术加qq交流群:906392632
最后感谢各位的耐心观看,既然都到这了,点个 👍赞再走吧!