React Hooks(二) useEffect

一 介绍

useEffect是在React更新DOM之后运行一些额外的代码,也就是执行副作用操作,比如请求数据,设置订阅,手动更改React组件中的DOM等。

二 用法

useEffect(() => {
    
    
  // 相当于 componentDidMount、componentDidUpdate
  console.log("code");
  return () => {
    
    
    // 相当于 componentWillUnmount
    console.log("code");
  }
}, [/*依赖项*/])

useEffect中定义了一个函数和一个数组,第二个参数决定了useEffect中各部分代码执行次数。
1.依赖项的几种情况:

  • 什么都不传,组件每次render之后useEffect都会调用,相当于componentDidMount和componentDidUpdate。
    注意,如果useEffect里的函数涉及到状态数据的变更,那么就会导致useEffect无限循环调用
  • 传入空数组[],只会调用一次,相当于componentDidMount
  • 传入一个数组,其中包括变量,只有当变量变化时,useEffect才会执行

注意:
其实对于函数式组件而言不存在生命周期,把class组件的生命周期概念搬过来对号入座只是一种辅助记忆手段。
2.return函数
如果useEffect中有监听事件或者定时器等,需要在return中关闭对应的监听事件和定时器

三 注意点

1.当依赖项是引用类型时,React会对比依赖项的内存地址是否一致。只有当不一致时,useEffect才会执行。

const [a, setA] = useState({
    
    
    b: 'dx',
    c: '18',
})

const changeA = () => {
    
    
    setA((old) => {
    
    
        old.b = 'yx'
        return old
    })
 }

/**当changeA执行却没有打印 a*/
useEffect(() => {
    
    
	console.log(a)
},[a])

常用的修改方法就是修改引用:

const [a, setA] = useState({
    
    
	b: 'dx',
	c: '18',
})

const changeA = () => {
    
    
    setA((old) => {
    
    
        const newA = {
    
    ...old}
        newA.b = 'yx'
        return newA 
    })
}


/**当changeA执行打印  {b:'yx',c:'18'}  */
useEffect(() => {
    
    
    console.log(a)
},[a])

2.看一个useEffect的例子

import React, {
    
     useState, useEffect } from 'react'
function App() {
    
    
  const [count, setCount] = useState(0) //默认值是0
  const [name, setName] = useState('张三') //默认值是0
  const [size, setsize] = useState({
    
    
    width: document.documentElement.clientWidth,
    height: document.documentElement.clientHeight,
  })
  const onResize = () => {
    
    
    setsize({
    
    
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
    })
  }
  //操作
  useEffect(() => {
    
    
    document.title = count
  }) //没有第二个参数就表示只要函数渲染就都执行
  
  useEffect(() => {
    
    
    //监听
    window.addEventListener('resize', onResize, false)
    //监听完了就考虑卸载,卸载的时候必须是return
    return () => {
    
    
      window.addEventListener('resize', onResize, false)
    }
  }, [])
  //空数组里面要是什么也不填写,那他只会发生在第一次渲染后和组件卸载之前执行
  // 也就是钩子函数componentDidMount 和componentWillUnMount
  
  useEffect(() => {
    
    
    console.log('count', count)
  }, [count])
  //只有count发生变化时候执行,和第一次渲染后以及组件卸载前执行

  useEffect(() => {
    
    
    document
      .querySelector('#size')
      .addEventListener('click', handleClick2, false)
    return () => {
    
    
      document
        .querySelector('#size')
        .removeEventListener('click', handleClick2, false)
    }
  })
  const handleClick2 = () => {
    
    
    console.log('点击了')
  }
  function handleClick() {
    
    
    setCount(count + 1)
    setName('李四')
  }

  return (
    <div>
      <span>
        {
    
    count}---{
    
    name}
      </span>
      {
    
    count % 2 === 0 ? (
        <span id="size">
          宽度是:{
    
    size.width}--高度是:{
    
    size.height}
        </span>
      ) : (
        <p id="size">
          宽度是:{
    
    size.width}--高度是:{
    
    size.height}
        </p>
      )}

      <button type="button" onClick={
    
    handleClick}>
        点击
      </button>
    </div>
  )
}

export default App

猜你喜欢

转载自blog.csdn.net/LittleMoon_lyy/article/details/124519252