一个简单的 useEffect 示例如下,它会在每次 render 之后执行,包括首次的 render 以及每次更新后的 render。
useEffect(() => {
console.log('useEffect with no dependency')
})
总的来说,如果你熟悉 React class 的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。可以通过控制其参数来实现。
不传参数
如下所示,每次都会执行,类似于componentDidUpdate。
useEffect(() => {
console.log('useEffect with no dependency')
})
但是我们知道,componentDidUpdate是可以控制更新策略的,只在某些情况下更新。
传入参数
传入参数,useEffect的第二个参数,即为其监控的对象,如果当前和上一次发生变化,则会出发useEffect,否则不触发。这样就可以实现很多功能。例如:
- componentDidMount
useEffect(() => {
console.log('useEffect with empty dependency')
}, [])
因为无论如何,空数组是不会发生变化的,所以只会执行一次,这便是componentDidMount。
- 可控的componentDidUpdate
useEffect(() => {
console.log('useEffect widh specify dependency')
}, [id, name])
第二个参数中传入多个数据,会比较每一个数据,一旦有一个发生变化,则触发useEffect的回调函数。
componentWillUnmount
useEffect(() => {
function handleStatusChange(status) {
setIsOnline(status.isOnline);
}
ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
// Specify how to clean up after this effect:
return function cleanup() {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};
});
如果在useEffect的回调函数中返回函数,则会在组件卸载的时候执行这个函数,这便是componentWillUnmount。
如果第二个参数是引用类型
如果第二个参数是对象或者数组之列的引用类型,如何有效的进行监听,可以通过JSON.stringfy来实现,代码如下所示
useEffect(() => {
console.log('useEffect widh specify dependency')
}, [JSON.stringify(obj)]])