深入理解 useEffect(适用于 React 与 Next.js)——新手指南
如果你刚开始学习 React 或 Next.js,你很可能最先接触到的 Hook 就是 useEffect。它一开始看起来有些神秘,但别担心——这篇指南会用清晰的方式一步一步讲透。
什么是 useEffect?
在 React 中,useEffect 是一个用于处理组件副作用(side effects)的 Hook。
所谓“副作用”,是指发生在 UI 渲染流程之外的行为。例如:
- 从 API 获取数据
- 监听用户事件(如滚动、窗口大小变化)
- 启动或清理定时器
- 与 localStorage 或其它浏览器 API 交互
一句话概括:useEffect 允许你在组件渲染之后执行代码。
基础示例
import { useEffect, useState } from "react";
export default function MyComponent() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("Component rendered!");
});
return (
<div>
<p>你点击了 {count} 次</p>
<button onClick={() => setCount(count + 1)}>点我</button>
</div>
);
}
这里发生了什么?
- 组件首次渲染时,会打印 "Component rendered!"。
- 每当 count 发生变化,组件会重新渲染——effect 也会再次运行。
依赖项数组(Dependency Array)
useEffect 接受第二个参数——依赖项数组,用来控制 effect 的触发时机。
useEffect(() => {
console.log("Runs only when `count` changes");
}, [count]);
- [] → 只在首次挂载时运行(适合初始化逻辑)。
- [count] → 当 count 变化时运行。
- 省略数组 → 每次渲染后都运行(除非必要,不推荐)。
清理副作用(Cleanup)
有些 effect 需要在适当时机进行清理,比如事件监听或定时器。 你可以在 useEffect 内返回一个函数,用于清理资源。
useEffect(() => {
const timer = setInterval(() => {
console.log("Tick...");
}, 1000);
// Cleanup when component unmounts or before running again
return () => {
clearInterval(timer);
console.log("Timer cleared!");
};
}, []);
Next.js 中的注意事项
由于 Next.js 支持服务端渲染(SSR),需要注意:
- useEffect 只会在客户端运行,不会在服务端执行。
- 因此你可以在 useEffect 中安全使用仅浏览器可用的特性(如 window、localStorage)。
核心要点回顾
- useEffect:在渲染后执行副作用。
- 依赖项数组决定 effect 何时运行。
- 返回一个函数用于清理(如定时器、事件监听)。
- 在 Next.js 中,它仅在浏览器端运行,不会在服务端运行。
