useEffect

useEffect的含义:副作用钩子,用于处理组件中的副作用,用来取代生命周期函数。所谓的"副作用"就是指的是组件中状态或生命周期改变时在useEffect可监听到。

如果熟悉class组件中生命周期方法,可以将useEffect视作coponentDidMount、componentDidUpdate和componentWillUnmount的组合体。

useEffect使用的几种方式,根据第二个参数的情况而定

  1. 无此参数:组件的任何更新,该 useEffect 对应的返回函数和函数都执行
  2. 为空数组:只在componentDidMount执行一次,不监听组件的更新,
  3. 数组中有具体依赖:对应的依赖数据,有变化的时候,才会执行(初始不会执行)

清除 effect

通常,组件卸载时需要清除 effect 创建的诸如订阅或计时器 ID 等资源。要实现这一点,useEffect 函数需返回一个清除函数。以下就是一个事件绑定的例子:

import { useState, useEffect } from "react";
import * as ReactDOM from "react-dom";

function App() {
  const [position, setPosition] = useState({x:0, y: 0})

  useEffect(()=>{
    console.log('点击了b')
    const mouseClickHandle = (e) =>{
      console.log('点击了c')
      setPosition({
        x: e.clientX,
        y: e.clientY
      })
    }
    document.addEventListener('click', mouseClickHandle)
    
    // return ()=>{
    //   console.log('点击了d')
    //   document.removeEventListener('click', mouseClickHandle)
    // }
  })
  console.log('点击了a')

  return (
    <>
      <p>
        X:{position.x}, Y: {position.y}
      </p>
    </>
  )
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

执行点击事件,可以看到打印结果如下:

微信截图_20211207151814.png

可以看到,当我第三次点击的时候,打印结果显示click事件被执行了两次,在这个示例中,意味着组件的每一次更新都会创建新的事件绑定,这很显然是不被允许的。
这个时候就需要使用清除函数,清除函数会在组件卸载前执行。另外,如果组件多次渲染(通常如此),则在执行下一个 effect 之前,上一个 effect 就已被清除

useEffect允许返回一个函数来解决上述问题:

 useEffect(()=>{
    console.log('点击了b')
    const mouseClickHandle = (e) =>{
      console.log('点击了c')
      setPosition({
        x: e.clientX,
        y: e.clientY
      })
    }
    document.addEventListener('click', mouseClickHandle)
    // 在此处返回一个解绑函数即可
    return ()=>{
      console.log('点击了d')
      document.removeEventListener('click', mouseClickHandle)
    }
 })
 console.log('点击了a')

当返回一个解绑函数后再次测试发现,在组件在执行下一个 effect 之前,上一个 effect 就已被清除(d在b之前打印可以印证这点)。


微信截图_20211207152514.png

下面再来印证上述提到的第二个参数为空数组的情况:

 useEffect(()=>{
    console.log('点击了b')
    const mouseClickHandle = (e) =>{
      console.log('点击了c')
      setPosition({
        x: e.clientX,
        y: e.clientY
      })
    }
    document.addEventListener('click', mouseClickHandle)
    
    return ()=>{
      console.log('点击了d')
      document.removeEventListener('click', mouseClickHandle)
    }
  },[])
  console.log('点击了a')
微信截图_20211207153514.png

可以看到,当第二个参数为空数组的时候,b和d都没有打印,说明此时useEffect并不被执行,执行的只是初始进入就绑定的事件。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容