useEffect

作者: 就问你怕不怕 | 来源:发表于2021-12-07 15:37 被阅读0次

    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并不被执行,执行的只是初始进入就绑定的事件。

    相关文章

      网友评论

          本文标题:useEffect

          本文链接:https://www.haomeiwen.com/subject/usfaxrtx.html