深入浅出React Hooks – 以react-hooks/exhaustive-deps为中心

一、简介

React Hooks是React 16.8推出的新特性,是一种更加优雅、简洁的处理组件状态和逻辑的方式,干掉了原有的Class组件,让函数组件具有了更加强大的能力。

react-hooks/exhaustive-deps是React Hooks中的一个重要概念,用于在useEffect Hook中控制副作用执行的依赖项,使代码更加健壮、稳定。

二、为什么需要控制副作用执行的依赖项

在使用useEffect Hook时,React会在DOM更新前执行useEffect副作用函数中的代码,以保证页面的正确性和流畅性。由于useEffect是基于函数式编程的思想实现,React并不能像Class组件中的生命周期函数一样自动清理副作用代码的引用,这就需要我们手动控制副作用执行的依赖项。

举个例子:一个简单的计数器函数组件,每点击一次按钮,计数器就会+1,并在useEffect中输出计数器的值:

import React, { useState, useEffect } from 'react';
  
function Counter() {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    console.log('count:', count)
  })
  
  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

但是,运行后我们发现,每点击一次按钮,控制台就会输出当前的count值,即使count并没有改变。这是因为,useEffect的执行是基于引用依赖,而每次点击按钮的时候,函数组件会被重新渲染,useEffect重新执行,此时的count依然是引用上一个count值的地址,所以console输出的值并没有改变。

这时候,就需要我们想办法控制useEffect的依赖项,规避这种无用执行的问题。

三、如何控制副作用执行的依赖项

1. 不指定依赖项

当useEffect的依赖项传空数组[]时,表明useEffect不依赖任何state或prop,仅在组件挂载和卸载时执行副作用代码。

useEffect(() => {
  console.log('component did mount');
  
  // 清理操作
  return () => {
    console.log('component will unmount');
  }
}, []) // 传空数组

这种方式适用于只需要在组件挂载和卸载时执行副作用代码,而不需要根据state或prop的变化执行的场景。

2. 指定部分依赖项

当useEffect的依赖项为指定的state或prop时,每次state或prop发生变化时,useEffect都会执行副作用代码。

useEffect(() => {
  console.log('count:', count)
}, [count]) // 指定count为依赖项

这种方式适用于只需要根据指定的state或prop变化来执行副作用代码的场景。

3. 指定所有依赖项

当useEffect的依赖项为所有state或prop时,每次任意一个state或prop发生变化时,useEffect都会执行副作用代码。在依赖项比较多的情况下,这种方式会造成性能问题,应当慎用。

useEffect(() => {
  console.log('effect:', count, size)
}, [count, size]) // 指定所有依赖项

四、控制依赖项出错的问题

虽然指定依赖项可以避免掉无用执行的问题,但是如果指定的依赖项不全、不正确的话,依然会带来错误和性能问题。

继续看一个例子:一个定时器函数组件,每1秒钟计数器+1,然后在useEffect中输出计数器的值。当props.count发生变化的时候,就会清空计数器。

import React, { useState, useEffect } from 'react';

function Timer(props) {
const { count } = props;
const [num, setNum] = useState(0);
let timer = null;

useEffect(() => {
startTimer();
return () => clearInterval(timer);
}, []);

useEffect(() => {
console.log('num:', num);
if (count !== 0) {
setNum(0);
}
}, [count]);

function startTimer() {
timer = setInterval(() => {
setNum(num => num + 1);
}, 1000);
}

return (

num: {num}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/312650.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2025-01-06 09:47
下一篇 2025-01-06 09:47

相关推荐

  • @uiw/react-amap介绍

    本文将详细阐述@uiw/react-amap的使用方法和参数配置,以及如何在React应用中集成高德地图组件。 一、@uiw/react-amap简介 @uiw/react-ama…

    编程 2025-04-29
  • ArcGIS更改标注位置为中心的方法

    本篇文章将从多个方面详细阐述如何在ArcGIS中更改标注位置为中心。让我们一步步来看。 一、禁止标注智能调整 在ArcMap中设置标注智能调整可以自动将标注位置调整到最佳显示位置。…

    编程 2025-04-29
  • CPU爆满怎么解决 Java为中心

    在Java编程中,难免会遇到CPU占用过高的情况,接下来从多个方面介绍如何解决CPU爆满问题。 一、优化代码 1、减少循环次数。循环体内不要放太多逻辑判断和计算,可以把计算提取出来…

    编程 2025-04-29
  • CMD如何升级为中心?

    本文将详细介绍在Windows操作系统下如何将CMD升级为中心,以及如何在升级后使用CMD中心进行操作。 一、下载Windows Terminal Windows Terminal…

    编程 2025-04-29
  • 如何使用GPU加速运行Python程序——以CSDN为中心

    GPU的强大性能是众所周知的。而随着深度学习和机器学习的发展,越来越多的Python开发者将GPU应用于深度学习模型的训练过程中,提高了模型训练效率。在本文中,我们将介绍如何使用G…

    编程 2025-04-29
  • 如何修改ant组件的动效为中心

    当我们使用Ant Design时,其默认的组件动效可能不一定符合我们的需求,这时我们需要修改Ant Design组件动效,使其更加符合我们的UI设计。本文将从多个方面详细阐述如何修…

    编程 2025-04-29
  • 黑夜不迷途打一中药名为中心

    中药作为中华民族独有的药物疗法,已经历了千百年的历史,在中医中发挥着重要的作用。其中有一种药物,以“黑夜不迷途”为谜底,是一种著名的中药。下面将从药物的组成、功效、用法等方面,进行…

    编程 2025-04-29
  • Python作为中心语言,在编程中取代C语言的优势和挑战

    Python一直以其简单易懂的语法和高效的编码环境而著名。然而,它最近的发展趋势表明Python的使用范围已经从脚本语言扩展到了从Web应用到机器学习等广泛的开发领域。与此同时,C…

    编程 2025-04-28
  • 全能编程开发工程师-以keysuper为中心

    keysuper,是一款能够实现各种编程语言的关键字补全和智能选单功能的插件,它的便利性在开发中发挥了越来越大的作用。以下是本文将为您详细介绍的内容: 一、keysuper为何具有…

    编程 2025-04-28
  • 为什么要除为中心进行平均分组

    平均分组是指将数据分为若干组,使得每组的数据之和尽可能相等,这样可以更好地控制数据波动,减少误差。然而,为什么要除为中心进行平均分组呢?本文将从多个方面进行阐述。 一、分组方式的影…

    编程 2025-04-28

发表回复

登录后才能评论