react实例与总结(一)
目录
一、简单认识
1.1、特点
1.2、JSX语法规则
1.3、函数组件和类式组件
1.4、类组件三大属性state、props、refs
1.4.1、state
1.4.2、props
1.4.3、refs
1.5、事件处理
1.6、收集表单数据—非受控组件和受控组件
1.7、高阶函数—函数柯里化
1.8、生命周期—新旧对比
1.8.1、旧16+
1.8.2、新17+
1.8.3、对比
1.9、DOM的Diffing算法
二、脚手架搭建
2.1、创建项目
因为真实DOM频繁操作节点会导致页面重绘和重排,影响性能,所以会用虚拟DOM【应用于前端框架】进行跨平台开发。
一、简单认识
英文:Getting Started – React
中文:快速入门 – React 中文文档
1.1、特点
(1)采用组件化模式、声明式编码,提高开发效率及组件复用率
(2)在React Native中使用它进行移动端开发
(3)使用虚拟DOM+Diffing算法,减少与真实DOM的交互
1.2、JSX语法规则
(1)、定义虚拟DOM时,不要写引号
(2)、标签中混入js表达式时要用{}
(3)、样式的类名指定不要用class,要用className
(4)、内联样式:要用style={{key:value}}形式
(5)、只有一个根标签,所有标签必须闭合
(6)、标签首字母
若小写字母开头,则将该标签转为html中同名元素;若html中没有该标签对应的同名元素,则报错
若大写字母开头,则react去找对应的组件,若找不到,则报错
在Microsoft Edge安装React Developer Tools扩展进行开发辅助,以下语法基于16+版本。
1.3、函数组件和类式组件
前者适用于简单组件(只能使用props属性,除非使用Hooks里的useRef 和 useState ),后者适用于复杂组件
<div id="root"></div><script type="text/babel">// 1.创建函数式组件function MyComponent() {return <h1>我是函数式组件</h1>;}// 2.渲染组件到页面ReactDOM.render(<MyComponent />, document.getElementById("root"));</script>
// 1.创建类式组件class MyComponent extends React.Component {render() {// render()中的this 指向当前组件实例return <h1>我是类式组件</h1>;}}// 2.渲染组件到页面ReactDOM.render(<MyComponent />, document.getElementById("root"));
1.4、类组件三大属性state、props、refs
注意:类组件里的render()会调用1+N次(只要state更新就变)
1.4.1、state
class MyMood extends React.Component {state = {isGood: false,number: 0,};render() {const { isGood, number } = this.state;return (<div><h1 onClick={this.changeMyMood}>今天心情很{isGood ? "好" : "糟糕"}</h1><h1 onClick={() => this.setState({ number: 10 })}>打个{number}分</h1></div>);}changeMyMood = () => {this.setState({isGood: !this.state.isGood,});};}ReactDOM.render(<MyMood />, document.getElementById("root"));
总结:
(1)、状态必须通过setState进行更新,且更新是一种合并,不是替换;
(2)、组件中render()方法中的this为组件实例对象,当this为undefined,如何解决?
a.通过函数对象的bind()强制绑定this;b.箭头函数
1.4.2、props
<div id="root1"></div>
<div id="root2"></div>
<div id="root3"></div><script type="text/babel">class Person extends React.Component {// 使用 PropTypes 进行类型检查static propTypes = {name: PropTypes.string.isRequired,//必传项sex: PropTypes.string,age: PropTypes.number,onSuccess: PropTypes.func};// 设置默认属性static defaultProps = {age: 18,sex: "男"};render() {const { name, age, sex } = this.props;return (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age + 1}</li></ul>);}}
ReactDOM.render(<Person name="tom" age={18} sex="男" onSuccess={onSuccess}/>, document.getElementById("root1"));// 批量传递 props 【{...x}】const backData = { name: '后端返回数据', age: 19, sex: "女" };
ReactDOM.render(<Person {...backData} />, document.getElementById("root2"));
ReactDOM.render(<Person name="jack" age={20}/>, document.getElementById("root3"));function onSuccess() {console.log('执行事件');}</script>
函数组件Props
function Person(props) {const { name, age, sex } = props;return (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age + 1}</li></ul>);}Person.propTypes = {name: PropTypes.string.isRequired, sex: PropTypes.string,age: PropTypes.number,};
ReactDOM.render(<Person name='tom' age={18} sex="男" />, document.getElementById("root"));
总结:
(1)、组件标签的所有属性都保存在props中,但是组件内部不要修改props数据;
(2)、批量传递:{...item}、类型检查:PropTypes、默认属性:defaultProps
1.4.3、refs
class MyComponent extends React.Component {showData = () => {const { input1 } = this.refs;alert(input1.value);};showData2 = () => {const { input2 } = this;alert(input2.value);};myRef=React.createRef();showData3 = () => {alert(this.myRef.current.value);};
render() {return (<div>{/* 1、字符串形式 */}<input ref="input1" type="text" placeholder="点击按钮提示数据" /> <button onClick={this.showData}>点击提示左侧数据</button> {/* 2、回调函数形式 */}<inputref={(c) => (this.input2 = c)}onBlur={this.showData2}type="text"placeholder="失去焦点提示数据"/> {/* 3、createRef API:存储被ref标识的节点,“专人专用” */}<inputref={this.myRef}onBlur={this.showData3}type="text"placeholder="createRef的使用"/></div>);}
}
ReactDOM.render(<MyComponent />, document.getElementById("root"));
总结:
(1)、直接访问和操作DOM元素或React组件实例;
(2)、使用
React.createRef()或者回调函数形式(类组件);使用useRef(函数组件)
1.5、事件处理
总结:
(1)、通过onXxx属性指定事件处理函数,事件通过事件委托【委托给组件最外层的元素】处理的;
(2)、通过event.target得到发生事件的DOM元素对象【高效】;
(3)、原生Js事件使用onclick,而React事件使用onClick【为了更好的兼容性】。
1.6、收集表单数据—非受控组件和受控组件

| 特性 | 受控组件 (Controlled) | 非受控组件 (Uncontrolled) |
|---|---|---|
| 值存储位置 | 存储在React组件的state中 | 存储在DOM中(使用ref访问) |
| 表单元素控制 | React通过state控制表单的值 | 浏览器控制,React不干涉 |
| 更新方式 | 用户输入时通过onChange更新state | 使用ref获取值,无需触发事件 |
| 适用场景 | 需要表单验证、交互或复杂逻辑时 | 简单表单,且无需与React状态紧密交互 |
| 代码复杂度 | 稍微复杂,需要维护状态和事件处理 | 简单,直接使用ref访问DOM |
1.7、高阶函数—函数柯里化

总结:
高阶函数:如果函数的参数或者返回值是函数,那么这个函数就是高阶函数。
常见有:Promise、setTimeout、arr.map()、call、apply、bind、...
函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的一种函数编码形式。·
或者:直接在视图上使用箭头函数,同时传入属性值和对应的event。
1.8、生命周期—新旧对比
1.8.1、旧16+
<script type="text/babel">class MyComponent extends React.Component {constructor(props) {console.log("构造器---constructor");super(props);this.state = { count: 0 };}componentWillMount() {console.log("组件将要挂载---componentWillMount");}componentDidMount() {console.log("组件挂载完毕---componentDidMount");}shouldComponentUpdate(nextProps, nextState) {console.log("组件是否需要更新---shouldComponentUpdate");return true;}componentWillUpdate() {console.log("组件将要更新---componentWillUpdate");}componentDidUpdate() {console.log("组件更新完毕---componentDidUpdate");}componentWillUnmount() {console.log("组件即将卸载---componentWillUnmount");}moveIt = () => {ReactDOM.unmountComponentAtNode(document.getElementById("root")); //卸载};addIt = () => {const { count } = this.state;this.setState({ count: count + 1 });};forceIt = () => {this.forceUpdate();};render() {console.log("挂载页面---render");const { count } = this.state;return (<div><h2>当前求和为:{count}</h2><button onClick={this.addIt}>点击+1</button><button onClick={this.moveIt}>销毁</button><button onClick={this.forceIt}>强制更新</button></div>);}}// A和B是父子关系class A extends React.Component {state = { carName: '奔驰' };changeCar = () => {this.setState({ carName: '宝马' });};render() {return (<div><div>A页面</div><button onClick={this.changeCar}>换车</button><B carName={this.state.carName} /></div>);}}class B extends React.Component {componentWillReceiveProps(nextProps) {console.log('B组件接收到新的属性(第一次不调)', nextProps);}render() {return <div>B组件接收的车是:{this.props.carName}</div>;}}// ReactDOM.render(<MyComponent />, document.getElementById("root"));ReactDOM.render(<A />, document.getElementById("root"));</script>

1.8.2、新17+
static getDerivedStateFromProps(props,state) {console.log("获取新的属性---getDerivedStateFromProps",props,state);return null;//返回null或者props}ReactDOM.render(<MyComponent count={199} />, document.getElementById("root"));
<style>.list {width: 200px;height: 150px;background-color: skyblue;overflow: auto;}.news {height: 30px;
</style>
class MyComponent extends React.Component {state = { newArr: [] }componentDidMount() {setInterval(() => {const { newArr } = this.stateconst news = '新闻' + (newArr.length + 1)this.setState({ newArr: [news, ...newArr] })}, 1000);}getSnapshotBeforeUpdate(prevProps, prevState) {return this.refs.list.scrollHeight;// 获取更新前的DOM节点}componentDidUpdate(prevProps, prevState, snapshot) {this.refs.list.scrollTop += this.refs.list.scrollHeight - snapshot;}render() {return <div className="list" ref="list">{this.state.newArr.map((item, index) => {return <div className="news" key={index}>{item}</div>})}</div>;}
}
1.8.3、对比
17+在16+的基础上新增了getDerivedStateFromProps、getSnapshotBeforeUpdate;
即将废弃 componentWillMount、componentWillReceiveProps、componentWillUpdate三个钩子。
1.9、DOM的Diffing算法
经典面试题:为啥key不能使用index,而是取id(唯一标识)?

总结:
1、使用 index 作为 key:
在列表项的顺序发生变化、增加或删除时,可能会导致错误渲染或状态丢失。
适用于列表项不变,且不涉及删除、增加或排序操作的简单情况。
2、使用 id 作为 key:
更稳定,能够确保元素在更新时保持一致,特别是在列表顺序发生变化时。
尤其是在动态数据列表(增、删、改、排序等操作)中使用。
二、脚手架搭建
2.1、创建项目
1、全局安装:npm i -g create-react-app【查看是否下载create-react-app --version】
2、切换到想创建项目的目录下:create-react-app react_app【Node版本在14+及以上】
3、进入项目文件夹:cd react_app
4、启动项目:npm start【修改package.json,重新下载
node_modules、package-lock.json来修改版本】
或者直接用:React--Umi和Dva_react dva-CSDN博客
相关文章:
react实例与总结(一)
目录 一、简单认识 1.1、特点 1.2、JSX语法规则 1.3、函数组件和类式组件 1.4、类组件三大属性state、props、refs 1.4.1、state 1.4.2、props 1.4.3、refs 1.5、事件处理 1.6、收集表单数据—非受控组件和受控组件 1.7、高阶函数—函数柯里化 1.8、生命周期—新旧…...
电路研究9.3——合宙Air780EP中的AT开发指南(含TCP 示例)
根据合宙的AT研发推荐, AT指令基本上也简单看完了,这里开始转到AT的开发了。 AT 命令采用标准串口进行数据收发,将以前复杂的设备通讯方式转换成简单的串口编程, 大大简化了产品的硬件设计和软件开发成本,这使得几乎所…...
Qt 数据库SQLite 使用【01】基本功能
1.开发背景 Qt 开发过程中难免需要存储数据,可以选择保存到本地文件,但是查找比较麻烦,所以就有了数据库,主要是方便查找数据,增删改查等操作,而 SqLite 属于数据库中轻量级的存在,适合本地数据…...
stm32小白成长为高手的学习步骤和方法
我们假定大家已经对STM32的书籍或者文档有一定的理解。如不理解,请立即阅读STM32的文档,以获取最基本的知识点。STM32单片机自学教程 这篇博文也是一篇不错的入门教程,初学者可以看看,讲的真心不错。 英文好的同学…...
大模型产品Deepseek(五)、本地安装部署(Docker方式)
DeepSeek 本地部署指南 DeepSeek是一款高效的智能搜索与推荐引擎,除了通过云端API提供服务外,它还支持本地部署,让开发者可以完全控制数据和计算资源。通过本地部署,您可以将DeepSeek集成到内部系统中,在私有环境下运行模型,减少对外部API的依赖,同时提升数据隐私性与响…...
Kafka 的消费offset原来是使用ZK管理,现在新版本是怎么管理的?
目录 基于 ZooKeeper 管理消费 offset 原理 缺点 新版本基于内部主题管理消费 offset 原理 优点 示例代码(Java) 在 Kafka 早期版本中,消费者的消费偏移量(offset)是存储在 ZooKeeper 中的,但由于 ZooKeeper 并不适合高频读写操作,从 Kafka 0.9 版本开始,消费偏…...
基于改进型灰狼优化算法(GWO)的无人机路径规划
内容: 基于改进型灰狼优化算法的无人机轨迹规划 GWO是一种群体智能优化算法,模仿灰狼的社会等级和狩猎行为。原始的GWO有一些局限性,比如容易陷入局部最优,收敛速度慢等,所以改进型的GWO可能通过不同的策略来优化这些…...
JS中|=是什么意思?
在JavaScript中,| 是一个位运算符的复合赋值操作,具体表示按位或赋值运算。这个操作符会对两个操作数进行按位或(|)运算,然后将结果赋值回左操作数。 let a 5; // 二进制表示为 0101let b 3; // 二进制表示为 0011a …...
快速上手Vim的使用
Vim Linux编辑器-vim使用命令行模式下所有选项都可以带数字底行模式可视块模式(ctrlV进入) Linux编辑器-vim使用 Vim有多种模式的编辑器。能帮助我们很快的进行代码的编辑,甚至完成很多其他事情。 默认情况下我们打开vim在命令模式下&#x…...
RPA与深度学习结合
什么是RPA RPA即机器人流程自动化(Robotic Process Automation),它是一种利用软件机器人模拟人类在计算机上的操作,按照预设的规则自动执行一系列重复性、规律性任务的技术。这些任务可以包括数据录入、文件处理、报表生成、系统…...
在阿里云ECS上一键部署DeepSeek-R1
DeepSeek-R1 是一款开源模型,也提供了 API(接口)调用方式。据 DeepSeek介绍,DeepSeek-R1 后训练阶段大规模使用了强化学习技术,在只有极少标注数据的情况下提升了模型推理能力,该模型性能对标 OpenAl o1 正式版。DeepSeek-R1 推出…...
长安汽车发布“北斗天枢2.0”计划,深蓝汽车普及全民智驾
2月9日,长安汽车智能化战略“北斗天枢2.0”计划暨深蓝汽车全场景智能驾驶解决方案发布会在重庆盛大召开。此次发布会标志着长安汽车正式迈入智能化战略的新纪元,携手众多“中国智驾合伙人”,共同开启全民智驾元年。 发布会上,长安…...
Aitken 逐次线性插值
Aitken 逐次线性插值 用 Lagrange 插值多项式 L n ( x ) L_n(x) Ln(x)计算函数近似值时,如需增加插值节点,那么原来算出的数据均不能利用,必须重新计算。为克服这个缺点,可用逐次线性插值方法求得高次插值。 令 I i 1 , i 2…...
docker 安装 Prometheus、Node Exporter 和 Grafana
Docker Compose 配置文件 docker-compose.yml services:prometheus:image: prom/prometheus:latestcontainer_name: prometheusvolumes:- ./prometheus.yml:/etc/prometheus/prometheus.yml # 挂载配置文件 - prometheus_data:/prometheus # 持久化数据存储 command:- --…...
【LeetCode 热题100】74:搜索二维矩阵(二分、线性两种方式 详细解析)(Go 语言实现)
🚀 力扣热题 74:搜索二维矩阵(详细解析) 📌 题目描述 力扣 74. 搜索二维矩阵 给你一个满足下述两条属性的 m x n 整数矩阵 matrix : 每行中的整数从左到右按非递减顺序排列。每行的第一个整数大于前一行的…...
元数据、数据元、数据元素、数据项 和 主数据的概念
一、元数据 1.概念 元数据,又称中介数据、中继数据,为描述数据的数据。主要是描述数据属性的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。 2.实例 数据库中,表的名称、表字段名、其他相关的描述信息&a…...
阿里云cdn怎样设置图片压缩
阿里云 CDN 提供了图像加速服务,其中包括图像压缩功能。通过设置图片压缩,可以显著减小图片文件的体积,提升网站加载速度,同时减少带宽消耗。九河云来告诉你如何进行图片压缩吧。 如何设置阿里云 CDN 图片压缩? 1. 登…...
白话文实战Nacos(保姆级教程)
前言 上一篇博客 我们创建好了微服务项目,本篇博客来体验一下Nacos作为注册中心和配置中心的功能。 注册中心 如果我们启动了一个Nacos注册中心,那么微服务比如订单服务,启动后就可以连上注册中心把自己注册上去,这过程就是服务注册。每个微服务,比如商品服务都应该注册…...
7. 基于DeepSeek和智谱清言实现RAG问答
课件链接:https://cloud.189.cn/t/VNvmyimY7Vna(访问码:e4cb)天翼云盘是中国电信推出的云存储服务,为用户提供跨平台的文件存储、备份、同步及分享服务,是国内领先的免费网盘,安全、可靠、稳定、…...
【数据结构】双向链表(真正的零基础)
链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的!在上篇我们学习了单向链表,而单向链表虽然空间利用率高,插入和删除也只需改变指针就可以达到!但是我们在每次查找、删除、访问..…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
OCR MLLM Evaluation
为什么需要评测体系?——背景与矛盾 能干的事: 看清楚发票、身份证上的字(准确率>90%),速度飞快(眨眼间完成)。干不了的事: 碰到复杂表格(合并单元…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...

