React中函数式组件与类组件有何不同?
Function Component 与 Class Component 有何不同
目录
Function Component 与 Class Component 有何不同
文章核心观点:
解释一下:
总结:
文章核心观点:
- Function components capture the rendered values.函数式组件捕获的是已经被render的值
解释一下:
请看代码:
Class component
class ProfilePage extends React.Component {showMessage = () => {alert('Followed ' + this.props.user);};handleClick = () => {setTimeout(this.showMessage, 3000);};render() {return <button onClick={this.handleClick}>Follow</button>;}
}
Function Component
function ProfilePage(props) {const showMessage = () => {alert('Followed ' + props.user);};const handleClick = () => {setTimeout(showMessage, 3000);};return (<button onClick={handleClick}>Follow</button>);
}
pjqnl16lm7 - CodeSandbox效果:

LiveDemo
这里有bug:
点击在Sophie的profile的时候,follow这个人,然后在三秒之内快速切换到另一个页面(dan)。Function弹出框的效果是follow sophie,class 弹出框 follow dan。
所以说,function 是我们想要的效果,但是class 不是我们想要的效果。
为什么会出现这种情况呢?
Class Component:
在Class Component中,this.props是通过类的实例来访问的,它指向组件的props。当setTimeout中的this.showMessage函数被调用时,它仍然引用了Class Component的实例,因此它可以访问最新的this.props,这是为什么你看到Class Component中的this.props.user是最新的值的原因。
Function Component:
在Function Component中,props是通过函数的参数传递的。当setTimeout中的showMessage函数被调用时,它只是一个普通的JavaScript函数,没有与Function Component的实例关联,因此它只能访问在函数定义时传递给它的props,而不是最新的props值。
React 文档中描述的 props 不是不可变(Immutable) 数据吗?什么是不可变数据?
React 中的 props 通常被描述为不可变(immutable)数据,这意味着一旦 props 被传递给组件,它们不应该在组件内部被直接修改。这种不可变性有助于确保组件的可预测性和稳定性,因为它防止了组件在不知情的情况下更改外部传递的数据。
然而,有一点需要注意:props 对象本身是不可变的,但传递给 props 的值可能是可变的。如果你将一个可变对象(例如一个数组或对象)作为 props 传递给组件,那么这个对象的内容可以在组件内部被修改。这并不违反 React 的不可变性原则,因为 React 控制的是 props 对象的不可变性,而不控制传递给 props 的值的不可变性。
function ParentComponent() {const mutableArray = [1, 2, 3];return <ChildComponent items={mutableArray} />;
}
在这种情况下,mutableArray 是一个可变的数组。如果在 ChildComponent 内部修改了 items 数组,它将影响到原始数组。这并不是 React 的 props 不可变性引起的问题,而是因为 JavaScript 中的对象和数组是引用类型。如果你希望在 ChildComponent 中不修改原始数组,可以在内部创建副本来操作数据,以保持原始数据的不可变性。
总之,React 中的 props 本身是不可变的,但你需要注意传递给 props 的值的可变性,特别是当传递引用类型的值时。在组件内部,始终确保遵循不可变性原则,以避免意外的副作用。
有没有办法解决这个问题?
class ProfilePage extends React.Component {render() {// Capture the props!const props = this.props;// Note: we are *inside render*.// These aren't class methods.const showMessage = () => {alert('Followed ' + props.user);};const handleClick = () => {setTimeout(showMessage, 3000);};return <button onClick={handleClick}>Follow</button>;}
}
通过在 render 方法内部创建一个局部变量 props 并将其设置为 this.props 的值,你捕获了初始渲染时的 props 值。这意味着 props 变量将包含初始渲染时传递给组件的值,不受后续渲染的影响。
这种方法有时被用来解决在闭包函数(如 showMessage 和 handleClick 中的函数)中访问最新 props 值的需求。由于在函数内部,props 变量是一个常数(const),所以它将保持对初始 props 值的引用,不会随后的渲染而改变。
那么我想在Function Component中,如何获取到最新的数据?
使用React的useEffect钩子,以依赖props的变化来执行相应的操作。这样,当props更新时,useEffect内的代码会重新运行,确保你获取到最新的props值。
import { useEffect } from 'react';function ProfilePage(props) {useEffect(() => {// 依赖props的变化,当props更新时,这里的代码会重新运行console.log(props);}, [props]);
}
那么在异步的时候,为什么有捕获到初始值的情况?
Function Components是纯函数,它们的行为在某种程度上类似于闭包。当函数组件被创建时,它会捕获当前的作用域(包括props和其他变量)。这意味着在函数组件内部,函数参数(包括props)的值在组件的整个生命周期内保持不变,即使父组件在此期间重新渲染了。
function MyComponent(props) {const someValue = props.someProp;setTimeout(() => {console.log(someValue); // 这里的someValue是在组件初始渲染时捕获的值}, 3000);
}
在这个示例中,someValue 变量在组件初始渲染时捕获了 props.someProp 的值,即使在异步操作中访问 someValue,它仍然保持不变,因为它是在函数作用域内被捕获的。
这就是为什么在Function Component中,在异步操作中可能会访问到初始的props值的原因。如果你希望在异步操作中访问最新的props值,你可以使用React的useEffect Hook来处理副作用,以依赖props的变化来执行相应的操作。这样,当props更新时,useEffect内的代码会重新运行,确保你获取到最新的props值。
总结:
1.class component 使用this 指向可以获取到实例中最新的props值。function component 是个纯函数,相当于闭包,捕获的值就是当前作用域的值。
2.如果function component想获取到最新的值,可以使用hooks,如useEffect,来处理副作用,并在props变化时执行相应的操作,以确保获取到最新的props值。
3.React 中props的不可变性,指的是不要在组件中对它进行修改。所以使用function component纯函数更好,结果值只与参数有关,不会对外部产生副作用。
函数式组件与类组件有何不同? — Overreacted
精读《Function VS Class 组件》 - 掘金 (juejin.cn)
相关文章:
React中函数式组件与类组件有何不同?
Function Component 与 Class Component 有何不同 目录 Function Component 与 Class Component 有何不同 文章核心观点: 解释一下: 总结: 文章核心观点: Function components capture the rendered values.函数式组件捕获…...
windows11安装docker时,修改默认安装到C盘
1、修改默认安装到C盘 2、如果之前安装过docker,请删除如下目录:C:\Program Files\Docker 3、在D盘新建目录:D:\Program Files\Docker 4、winr,以管理员权限运行cmd 5、在cmd中执行如下命令,建立软联接: m…...
python模块之 aiomysql 异步mysql
mysql安装教程 mysql语法大全 python 模块pymysql模块,连接mysql数据库 一、介绍 aiomysql 是一个基于 asyncio 的异步 MySQL 客户端库,用于在 Python 中与 MySQL 数据库进行交互。它提供了异步的数据库连接和查询操作,适用于异步编程环境 …...
开开心心带你学习MySQL数据库之第八篇
索引和事务 ~~ 数据库运行的原理知识 面试题 索引 索引(index) > 目录 索引存在的意义,就是为了加快查找速度!!(省略了遍历的过程) 查找速度是快了,但是付出了一定的代价!! 1.需要付出额外的空间代价来保存索引数据 2.索引可能会拖慢新增,删除,修改的速度 ~~ …...
yml配置动态数据源(数据库@DS)与引起(If you want an embedded database (H2, HSQL or Derby))类问题
1:yml 配置 spring:datasource:dynamic:datasource:master:url: jdbc:mysql://192.168.11.50:3306/dsdd?characterEncodingUTF-8&useUnicodetrue&useSSLfalse&tinyInt1isBitfalse&allowPublicKeyRetrievaltrue&serverTimezoneUTCusername: ro…...
yolov5运行过程遇到的小问题(随时更新)
1.关于git的问题 解决办法:插入下面代码 import os os.environ["GIT_PYTHON_REFRESH"] "quiet"2.页面太小无法完成操作 解决办法: 如果不好使再考虑降低Batch_Size大小或者调整虚拟内存可用硬盘空间大小!(调整虚拟内存…...
使用FabricJS创建Image对象的JSON表示
本篇文章介绍一下如何创建图像的 JSON 表示形式 使用 FabricJS 的对象。我们可以通过创建一个实例来创建一个 Image 对象 织物.图像。由于它是FabricJS的基本元素之一,我们也可以轻松地 通过应用角度、不透明度等属性来自定义它。为了创建 JSON Image 对象的表示&am…...
【牛客刷题】反转固定区间链表、每k个节点一组反转
链表内指定区间反转_牛客题霸_牛客网 ListNode* reverseList(ListNode* head, ListNode* tail) {ListNode* pre nullptr;ListNode* cur head;while (cur ! tail) { 最后cur就是tailListNode* temp cur->next;cur->next pre;pre cur;cur temp;}return pre;}ListNode…...
算法:数组常见套路1---双指针、取模、打擂台法
文章来源: https://blog.csdn.net/weixin_45630258/article/details/132738318 欢迎各位大佬指点、三连 一、数组的合并–双指针[快慢指针] 1、题目: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ࿰…...
App 出海实践:Google Play 结算系统
作者:业志陈 现如今,App 出海热度不减,是很多公司和个人开发者选择的一个市场方向。App 为了实现盈利,除了接入广告这种最常见的变现方式外,就是通过提供各类虚拟商品或者是会员服务来吸引用户付费了,此时 …...
国际慈善日 | 追寻大爱无疆,拓世科技集团的公益之路
每年的9月5日,是联合国大会正式选定的国际慈善日。这一天的设立,旨在通过提高公众对慈善活动的意识,鼓励慈善公益活动通过各种形式在全球范围内得到增强和发展。这是一个向慈善公益事业致敬的日子,同时也是呼吁全球团结一致共同发…...
关于DNS的一些认识
目录 什么是DNS? 一台具有单个DNS的机器可以拥有多个地址吗? 一台计算机可以有多个属于不同顶级域的DNS名字吗? 什么是DNS? DNS是域名系统(Domain Name System)的缩写,它是互联网中用于将域名…...
游戏性能优化
Unity性能优化主要包括以下方面: 1.渲染性能 。包括减少Draw Calls、减少三角面数、使用LOD、使用批处理技术、减少实时光源等,以提高游戏的帧率和渲染效率。 2.内存性能 。包括使用对象池、使用合适的纹理、使用异步加载资源等,以减少内存占…...
公开游戏、基于有向图的游戏
目录 〇,背景 一,公开游戏、策梅洛定理 1,公开游戏 2,策梅洛定理 二,有向图游戏 1,狭义有向图游戏 2,广义有向图游戏 3,狭义有向图游戏的SG数 4,Bash Game 力扣…...
CSS学习笔记05
CSS笔记05 定位 position CSS 属性position - 用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置。position 有以下常用的属性值: position: static; - 默认值。指定元素使用正常的布局行为&am…...
Linux查看指定端口是否被占用
在Linux中,可以使用多种方法来检查一个特定端口(例如3306,通常由MySQL使用)是否被占用: 使用netstat命令: 如果系统中已安装了netstat,可以使用以下命令检查3306端口: netstat -tuln | grep 330…...
【Python 自动化】小说推文一键生成思路概述
最近看了一下小说推文成品软件的思路,发现可以完全迁移到我的 BookerAutoVideo 上面来。这篇短文里面,我试着分析一下整个推文视频生成的流程,以及简要阐述一下有什么工具。 整体流程是这样: 分句 原文是按照段落组织的…...
MySQL中的字符集与排序规则详解
在 MySQL 中,字符集(Character Set)用于确定可以在数据库中存储的字符集合,而排序规则(Collation)用于指定比较和排序字符串的规则。下面是关于 MySQL 中字符集和排序规则的一些详细信息: 字符集…...
Java中如何进行加锁??
笔者在上篇文章介绍了线程安全的问题,接下来本篇文章就是来讲解如何避免线程安全问题~~ 前言:创建两个线程,每个线程都实现对同一个变量count各自自增5W次,我们来看一下代码: class Counter{private int count0;publi…...
Pytorch3D多角度渲染.obj模型
3D理解在从自动驾驶汽车和自主机器人到虚拟现实和增强现实的众多应用中发挥着至关重要的作用。在过去的一年里,PyTorch3D已经成为一个越来越流行的开源框架,用于使用Python进行3D深度学习。值得庆幸的是,PyTorch3D 库背后的人员已经完成了实现…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
