首页 > 其他分享 >react useEffect可以作为watch监听值变化,进行其他操作用吗

react useEffect可以作为watch监听值变化,进行其他操作用吗

时间:2024-05-07 19:24:20浏览次数:26  
标签:count obj watch react const useEffect 变化 监听

是的,React中的useEffect Hook 可以被用来作为“watch”监听特定变量或状态的变化,并在这些值发生变化时执行特定的操作。这是通过在useEffect的依赖数组中列出你想要监听的值来实现的。当依赖数组中的某个值发生变化时,useEffect的回调函数会被重新执行。

下面是一个简单的例子,展示了如何使用useEffect来监听count状态的变化并执行操作:

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

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

  // 使用useEffect监听count的变化
  useEffect(() => {
    // 当count变化时,这个函数会被执行
    document.title = `You clicked ${count} times`;
    
    // 注意:如果useEffect中有设置定时器或其他需要清理的副作用,
    // 应该返回一个清理函数。在这个例子中,因为我们没有这类操作,所以不需要返回。
  }, [count]); // <- count作为依赖项列在这里

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

export default Example;

在这个例子中,每当count的值因为按钮点击而更新时,useEffect的回调函数就会执行,从而更新文档的标题来反映最新的点击次数。
通过将count作为依赖数组[count]的一部分,我们告诉React只有当count的值变化时才需要重新运行这个副作用。

但是如果useEffect的第二个参数有好多值,甚至包括对象,只要有一个变化,就会执行useEffect,该如何知道是哪个值的变化导致的useEffect的执行?

useEffect的依赖数组中有多个值,包括可能的对象,确实每次只要其中任何一个值发生变化,useEffect的回调函数就会执行。然而,React本身并不直接提供一种机制来告诉你具体是哪个依赖导致了重渲染或useEffect的重新执行。但是,你可以通过自定义的方式来间接实现这一需求。

方法一:手动比较

useEffect内部,你可以对每个依赖值进行前后比较,以此来确定是哪个值发生了变化。虽然这种方法在处理简单类型(如数字、字符串)时较为直观,但对于复杂对象的深度比较则会相对复杂。

方法二:使用ref记录旧值

你可以为每个你关心其变化的依赖值使用useRef来保存它们的上一次值,然后在useEffect内部比较当前值与上一次的值。

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

function Example() {
  const [count, setCount] = useState(0);
  const [obj, setObj] = useState({ value: 0 });
  const prevCountRef = useRef(count);
  const prevObjRef = useRef(obj);

  useEffect(() => {
    if (prevCountRef.current !== count) {
      console.log('count发生了变化');
    }
    if (JSON.stringify(prevObjRef.current) !== JSON.stringify(obj)) {
      console.log('obj发生了变化');
    }
    
    // 更新ref的值以供下一次比较
    prevCountRef.current = count;
    prevObjRef.current = obj;
  }, [count, obj]); // <- count和obj都是依赖项

  return (
    // ...
  );
}

请注意,对于复杂对象的比较,上述示例使用了JSON.stringify,这在大多数情况下有效但可能不适用于所有情况,特别是当对象中包含循环引用或者特殊类型的值(如函数)时。
对于更精确的对象比较,你可能需要引入深比较的库,如lodash_.isEqual方法。

方法三:定制化的Hook

对于更复杂的场景,你可以考虑创建自定义Hook,封装这些比较逻辑,使其更加复用和易于管理。

通过上述方法,你可以在一定程度上了解是哪个依赖值的变化触发了useEffect的执行,尽管这种方式需要手动实现额外的逻辑。

标签:count,obj,watch,react,const,useEffect,变化,监听
From: https://www.cnblogs.com/longmo666/p/18178183

相关文章

  • mac 创建React Native项目遇到的问题
    ReactNative创建项目遇到的问题1.创建项目时提示:⠧ProcessingtemplateUsageError:Thenearestpackagedirectory(/Users/huang/Documents/develop/RN/myRn)doesn'tseemtobepartoftheprojectdeclaredin/Users/huang.-If/Users/huangisn'tintendedtobe......
  • [Unit testing - React] Use the waitForElementToBeRemoved Async Util to Await Unt
    Sometimes,youmightneedtowaitforanelementtodisappearfromyourUIbeforeproceedingwithyourtestsetupormakingyourassertion.Inthislesson,wewilllearnaboutawrapperaroundthewaitForthatallowsyoutowaituntilanelementisremove......
  • [Unit Testing - React] Use the Testing Playground to Help Decide Which Query to
    Queryingisdifficult!Evenifwefollowtheguidingprinciplesandalwaysstartfromthequeriesaccessibletoeveryone,weareboundtogetstucksometimes.Tohelpusout,theTestingPlaygroundwascreated.Inthislesson,wearegoingtoseehowtou......
  • 界面控件DevExtreme v23.1、v23.2盘点 - 增强的TypeScript(Angular、React、Vue)
    DevExtreme拥有高性能的HTML5/JavaScript小部件集合,使您可以利用现代Web开发堆栈(包括React,Angular,ASP.NETCore,jQuery,Knockout等)构建交互式的Web应用程序。从Angular和Reac,到ASP.NETCore或Vue,DevExtreme包含全面的高性能和响应式UI小部件集合,可在传统Web和下一代移动应用程序中......
  • react中事件冒泡导致弹窗关不掉
    代码如下<Modalactions={[{text:'Cancel',variant:'secondary',onClick:()=>setDeleteAutomatedReportModalVisible(false),},/>点击Cancel按钮,弹窗应该关闭才对,......
  • React入门
    React极简入门:从JavaScript到React-知乎(zhihu.com) HTML<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>Mytestpage</title></head><body><h1>这是标题一</h1>......
  • 为什么我不选择React、Vue.js作为SAAS网站的前端框架
    引言“道”在中国哲学中,是一个重要的概念,表示“终极真理”。“道”这一概念,不单为哲学流派诸子百家所重视,也被宗教流派道教等所使用。大道至简的意思就是大道理是极其简单的,简单到一两句话就能说明白。所谓“真传一句话,假传万卷书”。正文在开启独立创作之路时,我也考虑过各种......
  • REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS
    发表时间:2023(ICLR2023)文章要点:文章提出一个简单有效的ReAct框架,将reasoning和action结合,在交互式的环境上进行测试,取得了很好的效果。其中reasoning作为推理模块,帮助模型归纳,跟踪和更新动作规划,acting和环境交互收集更多信息(reasoningtraceshelpthemodelinduce,track,a......
  • 以React16.4为界限,比较生命周期的异同
    一、整体流程简介:新版:旧版:二、比较通过两个图的对比,可以发现:1.生命周期都包含创建、更新、销毁;2.新版本减少了以下三种方法:componentWillMountcomponentWillReceivePropscomponentWillUpdate其实这三个方法仍然存在,只是在前者加上了UNSAFE_前缀,如UNSAFE_componentW......
  • useEffect中的deps数组经常依赖了好多变量,甚至包括对象,如何避免这样,假如某个变量变化
    避免在useEffect的依赖数组中包含大量变量或对象,可以通过以下几种策略来优化:拆分useEffect:如果不同的副作用依赖于不同的状态或变量,可以将它们拆分为多个useEffect调用。这样每个useEffect只关注自己关心的依赖项,使逻辑更加清晰且易于维护。useEffect(()=>{//仅当a变化......