React Hooks 指北(二):useEffect

233 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

1.useEffect基本用法

useEffect是react的副作用函数,其可以模拟生命周期 mounted和destrory和监测指定数据的更新

//参数1是函数,参数2是数组
useEffect(()=>{

},[])

2.useEffect的使用特点

首次加载和数据更新时都会执行

首先我们清楚,react的useState数据更新时,其整个函数组件都会被重新加载一次。这个和vue是不同的。

import {useEffect, useState} from "react"
function StateTest () {
  let [num,setNum] = useState(1)
  useEffect(()=>{
      console.log("page load")
  })
  return (
    <div>
      <div>{num}</div>
      <div onClick={()=>setNum(num+1)}>修改num</div>
    </div>
  )
}

首次控制台输出page load。只要点击修改,组件都会被重新渲染,控制台打印page load

第二个参数

useEffect的第二个参数是一个数组,用于收集监听的依赖数据,注意只能用于监听useState定义的数据,如果是普通数据,无法监听。

当且仅当组件首次加载 和被监听数据发生改变时,useEffect的回调函数才会被触发。

import {useEffect, useState} from "react"
function StateTest () {
  let [num,setNum] = useState(1)
  let [age,setAge] = useState(22)
  useEffect(()=>{
    console.log("num load")
  },[number])

  return (
    <div>
      <div>{num}</div>
      <div>{age}</div>
      <div onClick={()=>setNum(num+1)}>修改num</div>
      <div onClick={()=>setAge(age+1)}>修改age</div>
    </div>
  )
}

image.png

  • 页面首次加载,打印num load.

  • 当我点击修改age时,组件重新加载,但是useEffect此时监听的是number.所以页面无变化。

  • 当我点击修改num时,组件重新加载,useEffect监听触发,页面打印num load

3.useEffect模拟声明周期

模拟首次加载:数据和页面dom都已经加载完成

第二个参数是空数组,如果不添加第二个参数,则页面任意的useState数据发生改变,则useEffect的操作都会二次执行。

useEffect(()=>{
    console.log("页面首次挂载")
},[])


模拟卸载

React的卸载特殊,分为组件重新渲染前的卸载(页面数据改变,导致函数组件被重新执行前的卸载)。另一种就是组件真正的卸载(组件页面发生了切换)

1.第二个参数是空数组:用于模拟组件切换的卸载

useEffect(()=>{
    console.log("页面首次挂载")
    return ()=>{
        console.log("页面切换被卸载")
    }
},[])

2. 第二个参数是变量:模拟该变量变化导致页面重新加载前的卸载

    useEffect(()=>{
        console.log("页面首次挂载后触发")
        return ()=>{
            console.log("num改变导致页面重新加载前的卸载")
        }
    },[num])

3.不添加第二个参数:模拟页面任意变量变化导致页面重新加载前的卸载

 useEffect(()=>{
    console.log("页面首次挂载后")
    return ()=>{
        console.log("页面任意数据改变导致页面重新加载前的卸载")
    }
})

模拟监听某个数据改变:数据和页面dom都已经更新

通过useEffect的第二个参数添加对应的数据就可以监听数据的改变。当且仅当页面首次加载和age发生改变时,会触发函数的执行。

useEffect(()=>{
    console.log("age改变")
},[age])

4.useEffect使用示例

需求1:页面首次加载后获取后端数据,其它情况不要重复加载

错误示范

useEffect(async()=>{
    加载后端数据操作
},[])

下面这个操作看起来没问题,但是react控制台会警告,它提示我们不能将async放在第一个函数的前面,需要我们在内部自定义函数,然后添加async

image.png

正确姿势

import {useEffect, useState} from "react"
import axios from "axios"
function StateTest () {
  const [num,setNum] = useState(1)
  const [list,setList] = useState([])

  useEffect(()=>{
    const getData = async() => {
      let msg = await axios.get("data.json")
      setList(msg.data.lists)
      console.log("首次加载后端数据")
    }
    getData()
  },[])

  return (
    <div>
      <div>num:{num}</div>
      <div onClick={()=>setNum(num+1)}>修改num</div>
      {list.map(item=><div key={item.age}>{item.name}:{item.age}</div>)}
    </div>
  )
}

页面首次加载,控制台输出 首次加载数据。无论其它依赖数据如何改变,页面的加载后端数据永远不会二次执行。

总结

以上是我的useEffet学习,希望给位老板动动小手点赞,评论,转发支持。