📌  相关文章
📜  React useEffect() 每次渲染后都会运行副作用 - Javascript(1)

📅  最后修改于: 2023-12-03 15:34:39.343000             🧑  作者: Mango

React useEffect() 每次渲染后都会运行副作用 - Javascript

React自版本16.8起,推出了Hooks,其中使用最多的Hook是useEffect。React官方文档对useEffect的定义是:“useEffect可以看作是componentDidMount,componentDidUpdate和componentWillUnmount的合集。” 也就是说,useEffect可以模拟生命周期方法,同时也可以完成一些其他的副作用操作。

useEffect的基本使用方法

useEffect接收两个参数,第一个参数是函数,第二个参数是一个数组(也可以不传),数组中包含了此useEffect的依赖项,只有当依赖项发生改变时才会重新执行useEffect。如果依赖项为空数组,则该useEffect只会在组件渲染完执行一次,相当于componentDidMount。如果没有传递第二个参数,则每次组件渲染时useEffect都会被调用。

import { useState, useEffect } from 'react'

function Example() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    console.log(`count has been updated to ${count}`)
  })

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}

上面的代码中,我们useEffect没有传递第二个参数,所以每当count发生变化时,都会打印一条信息。也就是说,useEffect每次渲染后都会执行。这个行为有时会引起一些问题。

useEffect每次渲染后都会执行的问题

有些情况下,我们并不需要在每次更新组件时都重复执行useEffect。例如,我们在useEffect中发送AJAX请求获取数据,并将数据存储到state中。如果每次组件更新时都发送请求,不但浪费了性能,也可能会导致数据不正确或重复。如下面的示例代码:

import { useState, useEffect } from 'react'
import axios from 'axios'

function Example() {
  const [data, setData] = useState([])

  useEffect(() => {
    axios.get('https://example.com/data').then(response => {
      setData(response.data)
    })
  })

  return (
    <div>
      {data.map(item => <p>{item}</p>)}
    </div>
  )
}

上面的代码中,我们每次更新组件时都会发送请求以获取数据,这可能会导致重复数据、不正确的数据以及性能问题。

解决每次更新都执行的方法
控制useEffect执行的条件

我们可以通过控制useEffect的执行条件,来避免不必要的请求或事件。

例如,如果只有在条件满足时才需要更新数据,我们可以将其移到useEffect的第二个参数中。这样,只有条件更改时,才会触发useEffect。

useEffect(() => {
  if (count > 0) {
    axios.get('https://example.com/data').then(response => {
      setData(response.data)
    })
  }
}, [count])

这样,只有在count大于0时,才会发出请求并更新数据。

指定空依赖项

有时候,我们需要在组件挂载时才执行一次useEffect,而不管依赖项的变化。

这时,我们可以将useEffect的第二个参数指定为空数组。这样一来,useEffect只会在组件挂载时执行,而不会在组件更新时执行。

useEffect(() => {
  axios.get('https://example.com/data').then(response => {
    setData(response.data)
  })
}, [])

这样,useEffect只会在组件挂载时执行一次,并且不会在组件更新时执行。

结语

在使用React Hooks的时候,useEffect是一个非常重要的Hook。虽然它可以模拟生命周期方法,但如果没有掌握好它的用法,则可能会导致一些不必要的问题。掌握好useEffect的使用方法,对于开发React应用是非常重要的一步。