使用 useEffect 让你的组件与外部世界同步,掌握依赖项与清理。
在 Kodokon 中打开本课一个 React 组件根据 props 和 state 计算出 JSX。任何超出这个范畴的事情——修改文档标题、启动定时器、订阅浏览器事件——都是副作用。useEffect 会在渲染之后执行这段代码,而不阻塞显示,并在某些值发生变化时重新同步它。
import { useEffect } from "react";
function CartTitle({ count }) {
useEffect(() => {
document.title = `Cart (${count})`;
}, [count]);
return <p>Items: {count}</p>;
}依赖数组控制着副作用的执行频率。[count]:在每一次 count 发生变化的渲染之后,副作用都会重新执行。[]:副作用只在首次渲染之后执行一次。不传数组:副作用会在每一次渲染之后重新执行,而这很少是你想要的。黄金法则:副作用内部用到的每一个组件值都必须出现在数组中。
import { useEffect, useState } from "react";
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setSeconds((s) => s + 1);
}, 1000);
return () => clearInterval(id);
}, []);
return <p>Elapsed: {seconds} s</p>;
}副作用返回的那个函数就是清理函数。React 会在每次重新执行副作用之前调用它,然后在组件卸载时最后再调用一次。正是它防止了泄漏:被遗弃的定时器、堆叠起来的监听器、永远没被取消的订阅。每一个“打开”了某样东西的副作用都必须把它再关上。
useEffect(() => {
function onResize() {
setWidth(window.innerWidth);
}
window.addEventListener("resize", onResize);
return () => {
window.removeEventListener("resize", onResize);
};
}, []);useEffect(fn, []) 时,函数 fn 在什么时候执行?userId,但它的依赖数组是 []。问题出在哪里?