-
在 React class 中,你通常会在 componentDidMount 中设置订阅,并在 componentWillUnmount 中清除它
-
那么在useEffect 中如何清除呢?由于添加和删除订阅的代码的紧密性,所以 useEffect 的设计是在同一个地方执行。如果你的 effect 返回一个函数,React 将会在执行清除操作时调用它
-
实例
componentDidMount() {
this.refreshData();
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll, false);
}
分别相当于
useEffect(()=>{
refreshData();
window.addEventListener('scroll', handleScroll)
},[])
useEffect(()=>{
return () => {
window.removeEventListener('scroll', handleScroll, false);
}
},[])
- 实例2 - 定时器,离开页面后清除定时器
tickFun =()=> {
// 读取最新的 num
console.log(this.state.num);
this.setState({
num:this.state.num+1
})
}
componentDidMount() {
this.timer = setInterval(this.tickFun,1000)
}
componentWillUnmount() {
clearInterval(this.timer)
}
和
const [count, setCount] = useState(0);
useEffect(() => {
const id = setInterval(() => {
setCount(c => c + 1); // ✅ 在这不依赖于外部的 `count` 变量
}, 1000);
return () => clearInterval(id);
}, []);
useEffect(()=>{
console.log(count)
},[count])
- 其他
useLayoutEffect
其函数签名与 useEffect 相同,但它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染。在浏览器执行绘制之前,useLayoutEffect 内部的更新计划将被同步刷新。
尽可能使用标准的 useEffect 以避免阻塞视觉更新。