useEffect 使用指南

140 阅读1分钟

一个简单的 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)]])