React组件之间的通信方式总结(下)
一、写一个时钟
- 用 react 写一个每秒都可以更新一次的时钟
import React from 'react'
import ReactDOM from 'react-dom'function tick() {let ele = <h1>{ new Date().toLocaleTimeString() }</h1>// Objects are not valid as a React child (found: Sun Aug 04 2019 20:34:51 GMT+0800 (中国标准时间)). If you meant to render a collection of children, use an array instead.// new Date() 是一个对象数据类型的值,React 元素不接收对象作为其子元素ReactDOM.render(ele, document.querySelector('#root'))
}tick()setInterval(tick, 1000) // 如果不包在一个函数中,时钟是不会每秒更新一次
但是 React 和 Vue 相同都是数据驱动的,但是这个时候和数据驱动没啥关系,每隔1秒钟重新创建一个 ele,然后再渲染到页面中,视图才发生变化;为了使用数据驱动,我们需要使用 React 的组件
二、React 的组件
在 React 组件中,jsx 元素(也称 react 元素)是组件的基本组成单位
在 react 中定义组件有两种方式:
- 函数(function)定义组件
- 类(class)定义组件
- 定义组件的要求:
-
- 组件的名字首字母必须大写,为了在写 jsx 时区分原生 html 标签
-
- 组件定义后,就可以当做一个标签在 jsx 语法中使用
-
- 如果使用函数定义组件必须返回一个 jsx 元素
2.1 React 的函数组件
react 使用函数定义组件,就是声明一个函数;
- 函数接收一个 props 参数;props 是对象,是在渲染或者父组件通过 prop(属性) 传递过来的数据;
- 函数返回一个 jsx 元素,在组件中需要的数据可以通过 props 传入;
// 1. 函数定义组件
function Welcome(props) {// props 是一个对象,是使用组件时,写在组件行内的属性和属性值组成的;console.log(data)return (<div><p>{props.data.name}; {props.data.age}</p><p>{props.x}</p></div>)
}ReactDOM.render(<Welcome data={{name: 'mabin', age: 18}} x='hahah' />, document.querySelector('#root'));
- ReactDOM.render() 会根据第一个参数的类型不同执行不同的操作;
-
- 如果是组件,当 render 执行时,首先会把当前组件的行内属性进行打包封装,把其封装成一个对象,把这个对象传给组件函数
-
- 执行组件函数,获取对应的虚拟 DOM 对象
-
- 把虚拟 DOM 转成真实 DOM 对象,并且插入到真实的 DOM 中
2.2 React 的 class 组件
通过 class 定义一个组件
- 通过 class 来定义一个组件,需要继承 React 上的 Component 这个类
- 在定义组件上的原型上必须有一个 render 函数,且 render 函数需要返回一个顶级的 jsx 元素
-看🌰
class Header extends Component {constructor () {super()}render () {// 在 render 函数中通过 this.props 访问 propsreturn (<div>{this.props.content}</div>)}
}class Hello extends Component {constructor (props) {super()// 注意在构造函数中不能访问 this.props ,props 会作为形参传入}render () {return (<div><Header content="现在是北京时间:" /><p>{this.props.data.toLocaleString()}</p></div>)}
}// 使用这个组件
ReactDOM.render(<Hello data={new Date()} />, document.getElementById('root'));
- ReactDOM.render() 渲染 class 声明的组件过程:
-
- 找到组件对应的类,然后 new 一下这个类,获得这个类的一个实例
-
- 通过实例找到当前类原型上的 render 函数,让 render 执行接收其返回的虚拟 DOM
-
- 将上一步的虚拟 DOM 转换成成真实 DOM ,插入到页面中
2.3 class 和 function 定义的组件有什么不同
React 也是数据驱动的,当数据发生变化时,视图就会自动发生变化(视图是数据的映射)。组件中的数据有两个来源:props 和 state,其中 props 就是组件被使用时接收的行内属性,是从外部传入的数据,而 state 是组件的私有数据,组件定义时就需要创建;
- class 定义的组件中有 this,state,生命周期的钩子,而 function 声明的组件只有 props;
三、数据映射视图
3.1 属性(props)映射视图
属性(prop)也是组件的数据,而视图是数据的映射,当数据发生变化,组件会自动重新渲染
-看🌰
function Welcome(props) {return <div>{props.time.toLocaleString()}</div>
}setInterval(() => {// 每隔一秒钟 new Date的值会发生变化,即 Welcome 的 time prop 属性发生了变化,而视图自动变化let now = new Date()ReactDOM.render(<Welcome time={now} />, document.querySelector('#root'))
}, 1000)
-看🌰
把数据通过属性传递给组,
参考 前端进阶面试题详细解答
function User(props) {console.log(props)let { name, age } = props;return <div><p>{name}</p><p>{age}</p></div>
}let data = {name: 'mabin',age: 18
}// ReactDOM.render(<User name={data.name} age={data.age} />, document.getElementById('root'))ReactDOM.render(<User {...data}/>, document.getElementById('root')) // 可以使用展开运算符把一个对象传给组件的props,等效于上面的写法
3.2 状态(state) 映射视图
react 组件的数据有两个来源:props 和 state
属性(props):是父组件传递过来的
状态(state): 是组件自己管控的状态,状态是组件私有的数据
3.2.1 使用 state
- 在 React 中如果使用 state 必须使用 class 创建组件;
- 在 constructor 中初始化一个状态;通过 this.state 赋值一个对象的形式初始化;
- state 中的数据不可以直接修改,如果要更新数据,需要调用 setState 方法 ,setState 方法会进行合并 setState有两种写法 一种是对象一种是函数,如果下一个状态依赖上一个状态,我们需要使用函数的形式
-
- 函数: this.setState((prevState) => {})
-
- 对象: this.setState({num: 5})
- state 发生改变后触发 render 函数执行更新 DOM
3.2.2 在 react 中绑定事件
- react 绑定事件时,需要使用驼峰命名法的事件名 onClick = { 事件处理函数 }
- 在定义事件函数时,一般把事件函数声明在原型上,而绑定事件时,通过 this.add 访问这个事件函数
- 示例:
我们来写一个计数器感受一下 React 的数据驱动
class Count extends Component {constructor () {super()// 在 constructor 中初始化一个状态;通过this.state 赋值一个对象的形式初始化;// 只有用类声明的组件才有 statethis.state = {num: 1,x: 2}// this.add = this.add.bind(this)}add = () => {// 在 react 中如果要修改 状态只能通过 this.setState() 方法修改// setState 方法会进行合并 setState 有两种写法 一种是对象一种是函数// 1. setState 可以接受一个回调,回调需要 return 一个新的 state 对象,新的对象中只需包含要修改的 属性即可,例如这里我们要修改 num,return 的对象只需要包含num不用包含 x,react 会自动合并// 如果下一个状态依赖上一个状态,我们需要使用函数的形式/*this.setState((prevState) => { console.log(prevState); // prevState 之前的状态对象 return { num: prevState.num + 1 } })*/// 2. setState 还可以接受一个对象,对象中需要包含要更新的 state 属性;this.setState({num: this.state.num + 1})// 我们发现,我们更新数据后,页面中使用 num 的地方的值也自动跟着改了;// react 同样是数据驱动的,当我们调用 setState 修改 state 时,react 会重新调用 render 函数,得到虚拟DOM 然后调用 DOM-diff 算法,把修改的那一部分重新渲染;}render () {// react 绑定事件时,需要使用驼峰命名法的事件名 onClick = { 事件处理函数 }// 在定义事件函数时,一般把事件函数声明在原型上,而绑定事件时,通过 this.add 访问这个事件函数return (<div><p>NUM: {this.state.num} </p><p>X: {this.state.x} </p><button onClick={this.add}>给num加1</button></div>)}
}ReactDOM.render(<Count />, document.getElementById('root'))
四、属性(props) 校验
和 Vue 的 props 一样,React 的 props 同样支持校验;React 的 props 校验需要三方的库 prop-types
4.1 安装 prop-types
yarn add prop-types --save
4.2 使用
使用 类型校验需要 在 class 创建组件时创建静态属性 propTypes,值是一个对象,对象的属性是需要校验的 属性,值对应的是校验规则;
- 类型校验看🌰
static propTypes = {name: PropType.string.isRequired, // 要求 name 是字符串类型 isRequired 表示必传age: PropType.number.isRequired // 要求 age 是数字类型,isRequired 表示必传
}
- 此外,还可以给 prop 设置默认值,同样是通过类的静态属性设置,在创建组件时需要配置 defaultProps 静态属性;该属性的值是一个对象,该对象中属性是要设置默认值的 prop,值是 prop 的默认值
static defaultProps = {name: '珠峰',age: 10}
- 完整🌰
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import PropType from 'prop-types'
// React 的props 同样可以校验,但是需要一个第三方的库 prop-typesclass User extends Component {constructor (props) {super()console.log(props) // 对象,把行内属性封装到一个对象中// props.name = 123 // 如果想对 props 进行修改,可以在 constructor 中进行修改}static propTypes = {name: PropType.string.isRequired, // 要求 name 是字符串类型 isRequired 表示必传age: PropType.number.isRequired // 要求 age 是数字类型,isRequired 表示必传}// 给props 设置默认值static defaultProps = {name: '京东',age: 19}render () {return (<div><p>{ this.props.name }</p><p>{ this.props.age }</p></div>)}
}let obj = {name: '张三',age: 18
};ReactDOM.render(<User {...obj} />, document.querySelector('#root'));
五、父子组件通信
5.1 父传子
在 React 中,父组件把数据传递给子组件,仍然是通过 props 的方式传递;
-看🌰
import React, { Component } from 'react'
import ReactDOM from 'react-dom'class Header extends Component {render () {return (<h1><p>{this.props.data}</p></h1>)}
}// 此时的 Panel 是父组件而 Header 是子组件,父子组件通信时父传子,仍然是通过 props 传递的
class Panel extends Component {render () {return (<div className="container"><p>{this.props.news}</p><Header data={this.props.min} /></div>)}
}let data = {news: '快下课了',min: '拖几分钟'
}ReactDOM.render(<Panel {...data} />, document.getElementById('root'))
5.2 子传父
在 React 中子组件修改父组件的方式和 Vue 不同;子组件如果想修改父组件的数据,父组件在使用子组件的时候,通过 props 传给子组件一个可以修改父组件的方法,当子组件需要修改父组件的数据时,通过 this.props 找到这个方法执行对应的方法
-看🌰
import React, { Component } from 'react'
import ReactDOM from 'react-dom'import 'bootstrap/dist/css/bootstrap.css'class Panel extends Component {static defaultProps = {a: 1}constructor () {super()this.state = {color: 'success'}}changeColor = (color) => {this.setState({color})}render () {return (<div className="container"><div className={`panel panel-${this.state.color}`}><div className="panel-heading">{this.props.head} </div><div className="panel-body">{this.props.body} </div>{/*通过 modifyColor 这个 props 把 Panel 组件的 changeColor 方法传递给 Footer 组件*/} <Footer type={this.state.color}modifyColor={this.changeColor} /></div></div>)}
}class Footer extends Component {change = () => {this.props.modifyColor('danger')}render () {return (<div className="panel-footer"><button className={`btn btn-${this.props.type}`} onClick={this.change}>变色</button></div>)}
}ReactDOM.render(<Panel head="头信息" body="信息主体"/>, document.getElementById('root'))// React 同样是单向数据流,即数据只能通过只能从父组件流向子组件
// 所以子组件如果想修改父组件的数据,父组件在使用子组件的时候,通过props传给子组件一个可以修改父组件的方法,当子组件需要修改父组件的数据时,通过this.props 找到这个方法执行对应的方法就可以了
相关文章:
React组件之间的通信方式总结(下)
一、写一个时钟 用 react 写一个每秒都可以更新一次的时钟 import React from react import ReactDOM from react-domfunction tick() {let ele <h1>{ new Date().toLocaleTimeString() }</h1>// Objects are not valid as a React child (found: Sun Aug 04 20…...

【RabbitMQ笔记07】消息队列RabbitMQ七种模式之Publisher Confirms发布确认模式
这篇文章,主要接收消息队列RabbitMQ七种模式之Publisher Confirms发布确认模式。 目录 一、消息队列 1.1、发布确认模式 1.2、案例代码 (1)引入依赖 (2)编写生产者【消息确认--单条确认】 (3…...

【华为OD机试模拟题】用 C++ 实现 - IPv4 地址转换成整数(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 去重求和(2023.Q1) 文章目录 最近更新的博客使用说明IPv4 地址转换成整数题目输入输出示例一输入输出说明示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,...
闭包与高阶函数
文中内容均来自于曾探《JavaScript设计模式与开发实践》的学习笔记。闭包作用域变量的作用域,就是指变量的有效范围。局部变量、全局变量。变量的搜索是从内到外而非从外到内的。变量的生命周期对于全局变量莱索,全局变量的生命周期是永久的,…...

人工智能轨道交通行业周刊-第35期(2023.2.20-2.26)
本期关键词:重庆智慧轨道、智能运维主机、标准轨距、地方铁路公报、景深、机器视觉应用 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通Rai…...
快慢指针判断链表是否有环
快慢指针判断链表是否有环 单链表有可能存在环,有些情况下要判断一个单链表是否有环。数组的有个快慢指针的方法,其实单链表和数组有相似的地方,可以使用快慢指针的方法。具体做法如下: 首先创建两个指针,它们初始时…...
《MongoDB入门教程》第26篇 聚合统计之$max/$min表达式
本文将会介绍两个 MongoDB 表达式,返回一组数据中最大值的 $max 表达式,以及返回一组数据中最小值的 $min 表达式。 $max 表达式 $max 表达式用于返回一组数据中的最大值,语法如下: { $max: <expression> }$max 表达式在…...

FPGA纯verilog解码SDI视频 纯逻辑资源实现 提供2套工程源码和技术支持
目录1、前言2、硬件电路解析SDI摄像头Gv8601a单端转差GTX解串SDI解码VGA时序恢复YUV转RGB图像输出FDMA图像缓存HDMI输出3、工程1详解:无缓存输出4、工程2详解:缓存3帧输出5、上板调试验证并演示6、福利:工程代码的获取1、前言 FPGA实现SDI视…...

JVM篇之垃圾回收
一.如何判断对象可以回收 1.引用计数法 只要一个对象被其他变量所引用,就让它的计数加1,被引用了两次就让它的计数变成2,当这个变量的计数变成0时,就可以被垃圾回收; 弊端:当出现如下图的情况࿰…...

尝试用程序计算Π(3.141592653......)
文章目录1. π\piπ2. 用微积分来计算π\piπ2.1 原理2.2 代码2.3 结果2.4 分析1. π\piπ π\piπ的重要性或者地位不用多说,有时候还是很好奇,精确地π\piπ值是怎么计算出来的。研究π\piπ的精确计算应该是很多数学家计算机科学家努力的方向…...
【异常检测三件套】系列3--时序异常检测综述
写在前面: 异常检测共包含3个内容,从多个方面剖析异常检测方法,本文为第三篇。过往内容请查看以下链接: 【异常检测三件套】系列1--14种异常检测算法https://blog.csdn.net/allein_STR/article/details/128114175?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%…...
关于SAP 错误日志解析
有时候启动或操作sap会出现故障,只是察看sap用户当前目录下的日志文件可能不得要领,此时有必要察看work目录下的一些trace. 以Linux系统为例,其他的也差不多。 instance说明 如下 DVEBMGS?? ABAP Central Instance D?? …...

java:自定义变量加载到系统变量后替换shell模版并执行shell
这里的需求前提是,在项目中进行某些操作前,需要在命令后对shell配置文件的进行修改(如ip、port),这个对于用户是不友好的,需要改为用户页面输入ip、port,后台自动去操作修改配置;那么…...

Redis高级删除策略与数据淘汰
第二章:Redis高级 学习目标 目标1:能够说出redis中的数据删除策与略淘汰策略 目标2:能够说出主从复制的概念,工作流程以及场景问题及解决方案 目标3:能够说出哨兵的作用以及工作原理,以及如何启用哨兵 …...

社畜大学生的Python之pandas学习笔记,保姆入门级教学
接上期,上篇介绍了 NumPy,本篇介绍 pandas。 目录 pandas 入门pandas 的数据结构介绍基本功能汇总和计算描述统计处理缺失数据层次化索引 pandas 入门 Pandas 是基于 Numpy 构建的,让以 NumPy 为中心的应用变的更加简单。 Pandas是基于Numpy…...

20_FreeRTOS低功耗模式
目录 低功耗模式简介 STM32低功耗模式 Tickless模式详解 Tickless模式相关配置 实验源码 低功耗模式简介 很多应用场合对于功耗的要求很严格,比如可穿戴低功耗产品、物联网低功耗产品等。 一般MCU都有相应的低功耗模式,裸机开发时可以使用MCU的低功耗模式。 FreeRTOS也…...
Hive的使用方式
操作Hive可以在Shell命令行下操作,或者是使用JDBC代码的方式操作 针对命令行这种方式,其实还有两种使用 第一个是使用bin目录下的hive命令,这个是从hive一开始就支持的使用方式 后来又出现一个beeline命令,它是通过HiveServer2服…...
Flume三大核心组件
Flume的三大核心组件: Source:数据源 Channel:临时存储数据的管道 Sink:目的地 Source:数据源:通过source组件可以指定让Flume读取哪里的数据,然后将数据传递给后面的 channel Flume内置支持读…...

数据结构(六)二叉树
一、树形结构概念树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:1、有一个…...

Docker buildx 的跨平台编译
docker buildx 默认的 docker build 命令无法完成跨平台构建任务,我们需要为 docker 命令行安装 buildx 插件扩展其功能。buildx 能够使用由 Moby BuildKit 提供的构建镜像额外特性,它能够创建多个 builder 实例,在多个节点并行地执行构建任…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

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

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

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...