前言
项目之前已经用了函数组件,后面的需求需要初始化组件的数据,那怎么实现componentDidMount()的效果呢? 答:用useEffect模拟实现。
下面结合官方文档介绍useEffect,以及如何模拟生命周期。(需要直接看结果的,直接拉到最后~~)
注意:只有class组件才有生命周期方法,函数组件是没有的。
Effect Hook
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。Effect Hook 可以让你在函数组件中执行副作用操作。
如果对hook不是很理解的可以看看这片文章:轻松学会 React 钩子:以 useEffect() 为例
Hook使用规则
- 只能在函数最外层调用,不要再循环、条件判断或者子函数中调用。
- 只能在React的函数组件中调用Hook
示例
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => { document.title = `You clicked ${count} times`; });
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
上面例子可以看出useEffect是怎样使用的。通过useEffect可以告诉React组件需要在渲染后执行某些操作。React会保存你传递的effect,并且在执行DOM更新之后调用它。而将useEffect放在组件内部让我们可以在effect中直接访问state变量,不需要特殊的API来读取它(已经保存在函数作用域中)。 默认情况下,useEffect在第一次渲染之后和每次更新之后都会执行。
useEffect
可以在组件渲染后实现各种不同的副作用。与componentDidMount
或componentDidUpdate
不同,使用useEffect
调度的 effect 不会阻塞浏览器更新屏幕,这让你的应用看起来响应更快。大多数情况下,effect 不需要同步地执行。
可清除的Effect
只需在effect 返回一个函数,React 将会在执行清除操作时调用它
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
在effect 返回一个函数,是 effect 可选的清除机制。每个 effect 都可以返回一个清除函数。React 会在组件卸载的时候执行清除操作。
注: React 会在执行当前 effect 之前对上一个 effect 进行清除。每次更新的时候都要运行 Effect,可以避免在 class 组件中因为没有处理更新逻辑而导致常见的 bug
useEffect
的第二个参数
是可以选参数,通过传入数组可以约束useEffect
在哪些数据需要更新时执行。(对于有清除操作的 effect 同样适用。)
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
模拟生命周期
通过前面的介绍,可以猜到是怎么实现了吧?来张官方文档截图~~~
- 示例
useEffect(() => {
// 相当于 componentDidMount
document.title = `You clicked ${count} times`;
return () => {
// 相当于 componentWillUnMount
...
}
}, []);
useEffect(() => {
// 相当于 componentDidUpdate
document.title = `You clicked ${count} times`;
});
- 效果