当前位置: 首页 > news >正文

Vue转React开发经验分享——hooks写法如何触发react生命周期、如何触发数据更新?

背景:习惯了vue的写法,并且vue2和vue3都比较熟悉,在转react开发中,不停的思考react和vue框架的相似之处,以及vue中的写法在react里怎么替换。本文将组件更新或组件生命周期角度出发聊聊如何使用hooks触发生命周期,以及如何触发数据更新

为什么要触发组件生命周期

很多没有经验的人不知道为什么要学习框架的生命周期。在开发中,我们经常需要弹窗和主页面进行数据传递,我现在就遇到很多组件通信的场景,主页面更新了,弹窗不能关闭,弹窗也要更新;又或者,弹窗更新了,立即更新外部页面,如tree的状态,视图更新等。这里先不考虑组件通信,之后在聊。先说组件如何触发更新。

组件什么时候更新?这里我们说的概念是主动触发更新。当你明确知道哪个数据变化了,一定要更新;或者执行了变更操作一定要更新我们就去触发更新。react的hook写法没有提供像vue这种onMounted,onUnMounted,watch等监控方法,同时它的数据必须通过组件更新才能重新渲染到视图。所以在用react开发的时候,更多的是在跟数据打交道,有时候莫名奇妙的数据变成undefined,或者数据更新了视图不更新。

useEffect

useEffect 是 React 中最常用的生命周期管理 Hook。它相当于类组件中的 componentDidMountcomponentDidUpdate 和 componentWillUnmount 的组合。 

useEffect模拟组件挂载和卸载 

 最常用的就是useEffect方法,这个方法能干什么?首先,它接受两个参数,第一个参数放执行逻辑,第二个参数放依赖数组。同时第一个参数的函数返回支持一个return方法。这几项共同演绎了组件更新逻辑。首先,如何模拟组件挂载和卸载,比如弹窗如果封装为一个组件,那么弹窗打开是挂载,弹窗关闭是卸载。你如果只想让组件执行一次挂载和卸载逻辑,就将依赖项设置一个空数组。在第一个参数写组件挂载逻辑,在返回return里执行卸载,即清理工作。

示例如下 

import React, { useEffect } from 'react';function Example() {useEffect(() => {// 这里执行的代码在组件首次渲染后只执行一次const interval = setInterval(() => {console.log('Interval running');}, 1000);// 返回一个清理函数,用于在组件卸载时清除定时器return () => {clearInterval(interval);console.log('Component unmounted');};}, []);return (<div>{/* 组件内容 */}</div>);
}

 Vue中的onMounted,可以在首次渲染后执行一些初始化操作。在React中,你可以通过useEffect的依赖项为空来实现这一点;

Vue中的onUnmounted,可以在组件卸载前执行一些清理操作;推荐使用useEffect的返回值来实现更安全的组件卸载逻辑

 useEffect模拟数据更新视图

在Vue中,组件的更新操作通常是由数据变化触发的,Vue会自动处理DOM的更新。而在React中,如果你想模拟Vue的组件更新操作,你可以使用useStateuseEffect钩子来手动控制组件的更新。通过useEffect设置依赖项,就可以在依赖项变化时触发其他数据的方法。比如删除数据后触发list刷新,保存数据后重新获取数据等。

import React, { useState, useEffect } from 'react';function Example() {const [count, setCount] = useState(0);useEffect(() => {// 组件更新时执行console.log(`Count changed to ${count}`);};}, [count]); // 依赖数组,当 count 变化时,重新执行 useEffectreturn (<div><p>Count is: {count}</p><button onClick={() => setCount(count + 1)}>Increment</button></div>);
}

如何触发数据更新

在vue中可以通过ref、reactive等方法直接定义响应式数据,数据变化视图自动更新。但是在react,数据需要手动管理,即哪些是需要视图跟着一起变化的数据需要手动维护。最常用的是useState钩子函数。这个函数通过解构重命名为[变量,变量的修改方法]。用法如下

 useState

import React, { useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);const handleClick = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={handleClick}>Increment</button></div>);
}

setState后异步获取state不是最新的?

如果在一个组件生命周期内,先通过方法更改了state,但是紧跟着就使用state,会出现用的还是旧的state数据。这是因为state还没更新,setState是异步的,state会在下个组件生命周期更新。所以你会发现你想的数据总是”晚一步“。这点非常不好用!!!如何避免?

解决方法

1.更新state时,用一个额外的变量存当前最新的state,可以用useRef维护一个全局变量,直接使用全局变量就行了;也可以用一个局部变量,然后立即使用这个局部变量

useRef 

useRef是React提供的一个Hook,用于创建一个保持初始值的可变引用。你可以在组件的函数中使用它来存储当前的状态值。 

import React, { useState, useRef } from 'react';function MyComponent() {// 使用useState创建状态const [count, setCount] = useState(0);// 使用useRef创建一个引用,用于存储当前的count值const currentCount = useRef(count);// 当count更新时,也更新当前的引用React.useEffect(() => {currentCount.current = count;}, [count]);return (<div><p>当前计数:{currentCount.current}</p><button onClick={() => setCount(count => count + 1)}>增加计数</button></div>);
}export default MyComponent;

 在函数组件中,你可以创建一个局部变量并立即使用它来存储当前的状态值。这样,你可以立即使用这个局部变量,而不用担心状态的延迟更新问题。

import React, { useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);// 创建一个局部变量来存储当前的count值
const update=()=>{
const new = count+1;setCount(new);
//需要立即使用最新countupdateOther(new);
}
const updateOther =(count:number)=>{
//巴拉巴拉
}return (<div><p>当前计数:{currentCount}</p><button onClick={update}>增加计数</button></div>);
}export default MyComponent;

setState更新对象不成功?

在React中,当使用setState更新对象时,如果直接修改状态对象,可能会导致原始数据丢失。这是因为React的setState函数在内部使用的是不可变数据结构,它会合并新的状态而不是替换整个对象。

以下是一个可能导致原始数据丢失的例子:

setState({age: prevState.userInfo.age + 1
});

在这个例子中,你首先获取了prevState.userInfo,然后直接在同一个对象上修改了age属性。这样做不会创建一个新的对象,因此React不会检测到状态的变化,所以界面不会更新。

解决方法

为了避免这种情况,你应该始终创建一个新的状态对象,如下所示:

setState({...prevState.userInfo,age: prevState.userInfo.age + 1
});

通常用展开运算符复用老数据,将需要修改的属性进行变更。

相关文章:

Vue转React开发经验分享——hooks写法如何触发react生命周期、如何触发数据更新?

背景&#xff1a;习惯了vue的写法&#xff0c;并且vue2和vue3都比较熟悉&#xff0c;在转react开发中&#xff0c;不停的思考react和vue框架的相似之处&#xff0c;以及vue中的写法在react里怎么替换。本文将组件更新或组件生命周期角度出发聊聊如何使用hooks触发生命周期&…...

算法入门-贪心1

第八部分&#xff1a;贪心 409.最长回文串&#xff08;简单&#xff09; 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回通过这些字母构造成的最长的回文串 的长度。 在构造过程中&#xff0c;请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串…...

element-plus的面包屑组件el-breadcrumb

面包屑组件主要用来显示当页面路径&#xff0c;以及快速返回之前的页面。 涉及2个组件 el-breadcrumb 和el-breadcrumb-item, el-breadcrumb的spearator指定item的分隔符 el-breadcrumb-item的to和replace属性和vue-router的一致&#xff0c;需要结合vue_router一起使用 用法…...

推荐几个网盘资源站给大伙,找资源更方便

夸克网盘在当前已然成为极为主流的网盘之一&#xff0c;其功能体验堪称强大&#xff0c;不仅支持在线解压阅读&#xff0c;磁力离线等功能也十分出色。那么&#xff0c;究竟该如何寻找夸克资源呢&#xff1f;下面&#xff0c;我就来为大家分享几个堪称神级的夸克资源网站。 一、…...

【Qt】Qml界面中嵌入C++ Widget窗口

1. 目的 qml做出的界面漂亮&#xff0c;但是执行效率低&#xff0c;一直想找一个方法实现qml中嵌入c界面。现在从网上找到一个方法&#xff0c;简单试了一下貌似可行&#xff0c;分享一下。 2. 显示效果 3. 代码 3.1 工程结构 3.2 pro文件 需要添加widgets > QT quick …...

Python快速入门 —— 第五节:接口开发

第五节:接口开发 目标: 学习使用Flask框架开发简单的Web接口,实现对学生信息的增删改查,通过HTTP请求与应用交互。 内容: Flask简介: Flask是一个轻量级的Python Web框架,使用简单,扩展性强,适合快速开发Web应用。安装Flask: pip install flask创建Flask应用: fr…...

利用secureCRT向虚拟机发送文件(secureCRT安装使用教程)

链接: secureCRT 链接:https://pan.baidu.com/s/1CvNYzoBbLVkyYNFq7hrT0g 提取码:5974 链接: secureCRT安装使用教程 链接:https://pan.baidu.com/s/1Bbi7SqyJBere8G53BCYL5A 提取码:xjw1...

AI杂七杂八系列(1)——工程篇

1. 远程服务器无法登录问题 2. 内存溢出解决方法 3. Padding 4. try...except...处理异常报错 5. view、expand、repeat、transpose、permute和squeeze、unsqueeze的区别 1. 远程服务器无法登录问题 权限可能是root权限&#xff0c;修改权限 用户权限&#xff1a; sudo c…...

学习大数据DAY58 增量抽取数据表

作业 1 SQL 优化的常见写法有哪些 - 面试经常被问 使用索引&#xff1a;合理创建和使用索引是提高查询效率的关键。索引可以加速数据的检 索速度&#xff0c;但是索引也会占用额外的存储空间&#xff0c;并且在插入、删除和更新操作时会 有额外的开销。 避免全表扫描&…...

HTTPTomcat

HTTP&Tomcat&Servlet 今日目标&#xff1a; 了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件 1&#xff0c;Web概述 1.1 Web和JavaWeb的概念 Web是全球广域网&#xff0c;也称为万维网(www)&#xff0c;…...

Python数据分析-Matplotlib快速入门

一、pyplot 二、绘图 1.绘制x和y的点 2.无线绘图 3.多点 4.默认x点 三、标记 1.标记 2.参考 3.格式化字符串 4.尺寸 5.颜色 四、线条 1.线形 两个都是设置虚线 2.更短的语法 3.线参考 4.线条颜色 5.线宽度 6.多条线 也可以 五、标签 1.为绘图创建标签 2.为绘图设置标题 3…...

重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估支持浏览器在线编程的系统架构设计

目录 案例 【题目】 【问题 1】(13 分) 【问题 2】(12 分) 【答案】 【问题 1】解析 【问题 2】解析 相关推荐 案例 阅读以下关于软件架构设计与评估的叙述&#xff0c;回答问题1和问题2。 【题目】 某公司拟开发一套在线软件开发系统&#xff0c;支持用户通过浏览器…...

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析

【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析 系列文章汇总:《鸿蒙OH-v5.0源码分析之 Uboot+Kernel 部分】000 - 文章链接汇总》 本文链接:《【鸿蒙OH-v5.0源码分析之 Linux Kernel 部分】003 - vmlinux.lds 链接脚本文件源码分析》 …...

MongoDB实现高级RAG:Parent-Document检索技术详解

MongoDB实现高级RAG&#xff1a;Parent-Document检索技术详解 引言 在人工智能和自然语言处理领域&#xff0c;检索增强生成(Retrieval-Augmented Generation, RAG)技术正在迅速发展。本文将介绍一种更高级的RAG实现方式&#xff1a;Parent-Document检索。我们将探讨如何使用…...

胡学乱想----前端知识点(css色彩)

1. margin 属性 简写 margin 属性有两个值时,它将 margin-top 和 margin-bottom 设置为第一个值,并将 margin-left 和 margin-right 设置为第二个值 .marker {width: 200px;height: 25px;background-color: red;margin: 10px auto; }2. rgb 属性 CSS 的 rgb 函数接收红色…...

GEE 案例——利用MODIS数据和NDWI指数进行美国五大湖水体计算和时序分析(直方图统计和面积统计)

目录 简介 MODIS数据 代码 结果 简介 利用MODIS数据和NDWI指数进行水体计算和时序分析(直方图统计和面积统计),这里我们统计了2001-2023年的美国五大湖的水域面积变化情况。 MODIS数据 MODIS/061/MOD09A1数据是由美国宇航局(NASA)的Moderate Resolution Imaging Spe…...

【jvm】记一次hive堆heap内存溢出的排查

先看下java的内存模型 监控jvm工具&#xff1a;visualVM 摘录一下内容&#xff1a; 由c开发的jvm&#xff0c;它巧妙地设计了java的设计理念——即万物皆对象。并设计了这些对象应该如何存储&#xff0c;如何调用&#xff0c;并通过不断迭代设计让对象的存储和回收&#xff0…...

编译运行 webAssembly(wasm)

环境准备&#xff1a; lunix下docker 参考https://hub.docker.com/r/emscripten/emsdk 拉编译环境 docker pull emscripten/emsdk 编译 随便找个目录&#xff0c;敲下面命令&#xff0c;编译一个webAssembly 程序 # create helloworld.cpp cat << EOF > hellowo…...

Linux bash 关联数组

目录 一. 关联数组定义二. 访问关联数组三. 元素的添加与删除四. 键值对的获取与遍历五. 实际应用5.1 读取封装配置文件内容5.2 收集系统信息 一. 关联数组定义 从 Bash 4.0 开始&#xff0c;Bash 支持关联数组。关联数组允许你将键和值配对&#xff0c;并通过键来访问值&…...

选择排序

一&#xff1a;基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完 。 解释&#xff1a;就是不断的找到最小的放在最左面&#xff0c;然后缩短数组&#xff0c;…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...