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

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="点击按钮提示数据" />&nbsp;<button onClick={this.showData}>点击提示左侧数据</button>&nbsp;{/* 2、回调函数形式 */}<inputref={(c) => (this.input2 = c)}onBlur={this.showData2}type="text"placeholder="失去焦点提示数据"/>&nbsp;{/* 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+的基础上新增了getDerivedStateFromPropsgetSnapshotBeforeUpdate

即将废弃 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研发推荐&#xff0c; AT指令基本上也简单看完了&#xff0c;这里开始转到AT的开发了。 AT 命令采用标准串口进行数据收发&#xff0c;将以前复杂的设备通讯方式转换成简单的串口编程&#xff0c; 大大简化了产品的硬件设计和软件开发成本&#xff0c;这使得几乎所…...

Qt 数据库SQLite 使用【01】基本功能

1.开发背景 Qt 开发过程中难免需要存储数据&#xff0c;可以选择保存到本地文件&#xff0c;但是查找比较麻烦&#xff0c;所以就有了数据库&#xff0c;主要是方便查找数据&#xff0c;增删改查等操作&#xff0c;而 SqLite 属于数据库中轻量级的存在&#xff0c;适合本地数据…...

stm32小白成长为高手的学习步骤和方法

我们假定大家已经对STM32的书籍或者文档有一定的理解。如不理解&#xff0c;请立即阅读STM32的文档&#xff0c;以获取最基本的知识点。STM32单片机自学教程 这篇博文也是一篇不错的入门教程&#xff0c;初学者可以看看&#xff0c;讲的真心不错。 英文好的同学&#xf…...

大模型产品Deepseek(五)、本地安装部署(Docker方式)

DeepSeek 本地部署指南 DeepSeek是一款高效的智能搜索与推荐引擎,除了通过云端API提供服务外,它还支持本地部署,让开发者可以完全控制数据和计算资源。通过本地部署,您可以将DeepSeek集成到内部系统中,在私有环境下运行模型,减少对外部API的依赖,同时提升数据隐私性与响…...

Kafka 的消费offset原来是使用ZK管理,现在新版本是怎么管理的?

目录 基于 ZooKeeper 管理消费 offset 原理 缺点 新版本基于内部主题管理消费 offset 原理 优点 示例代码(Java) 在 Kafka 早期版本中,消费者的消费偏移量(offset)是存储在 ZooKeeper 中的,但由于 ZooKeeper 并不适合高频读写操作,从 Kafka 0.9 版本开始,消费偏…...

基于改进型灰狼优化算法(GWO)的无人机路径规划

内容&#xff1a; 基于改进型灰狼优化算法的无人机轨迹规划 GWO是一种群体智能优化算法&#xff0c;模仿灰狼的社会等级和狩猎行为。原始的GWO有一些局限性&#xff0c;比如容易陷入局部最优&#xff0c;收敛速度慢等&#xff0c;所以改进型的GWO可能通过不同的策略来优化这些…...

JS中|=是什么意思?

在JavaScript中&#xff0c;| 是一个位运算符的复合赋值操作&#xff0c;具体表示按位或赋值运算。这个操作符会对两个操作数进行按位或&#xff08;|&#xff09;运算&#xff0c;然后将结果赋值回左操作数。 let a 5; // 二进制表示为 0101let b 3; // 二进制表示为 0011a …...

快速上手Vim的使用

Vim Linux编辑器-vim使用命令行模式下所有选项都可以带数字底行模式可视块模式&#xff08;ctrlV进入&#xff09; Linux编辑器-vim使用 Vim有多种模式的编辑器。能帮助我们很快的进行代码的编辑&#xff0c;甚至完成很多其他事情。 默认情况下我们打开vim在命令模式下&#x…...

RPA与深度学习结合

什么是RPA RPA即机器人流程自动化&#xff08;Robotic Process Automation&#xff09;&#xff0c;它是一种利用软件机器人模拟人类在计算机上的操作&#xff0c;按照预设的规则自动执行一系列重复性、规律性任务的技术。这些任务可以包括数据录入、文件处理、报表生成、系统…...

在阿里云ECS上一键部署DeepSeek-R1

DeepSeek-R1 是一款开源模型&#xff0c;也提供了 API(接口)调用方式。据 DeepSeek介绍&#xff0c;DeepSeek-R1 后训练阶段大规模使用了强化学习技术&#xff0c;在只有极少标注数据的情况下提升了模型推理能力&#xff0c;该模型性能对标 OpenAl o1 正式版。DeepSeek-R1 推出…...

长安汽车发布“北斗天枢2.0”计划,深蓝汽车普及全民智驾

2月9日&#xff0c;长安汽车智能化战略“北斗天枢2.0”计划暨深蓝汽车全场景智能驾驶解决方案发布会在重庆盛大召开。此次发布会标志着长安汽车正式迈入智能化战略的新纪元&#xff0c;携手众多“中国智驾合伙人”&#xff0c;共同开启全民智驾元年。 发布会上&#xff0c;长安…...

Aitken 逐次线性插值

Aitken 逐次线性插值 用 Lagrange 插值多项式 L n ( x ) L_n(x) Ln​(x)计算函数近似值时&#xff0c;如需增加插值节点&#xff0c;那么原来算出的数据均不能利用&#xff0c;必须重新计算。为克服这个缺点&#xff0c;可用逐次线性插值方法求得高次插值。 令 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 语言实现)

&#x1f680; 力扣热题 74&#xff1a;搜索二维矩阵&#xff08;详细解析&#xff09; &#x1f4cc; 题目描述 力扣 74. 搜索二维矩阵 给你一个满足下述两条属性的 m x n 整数矩阵 matrix &#xff1a; 每行中的整数从左到右按非递减顺序排列。每行的第一个整数大于前一行的…...

元数据、数据元、数据元素、数据项 和 主数据的概念

一、元数据 1.概念 元数据&#xff0c;又称中介数据、中继数据&#xff0c;为描述数据的数据。主要是描述数据属性的信息&#xff0c;用来支持如指示存储位置、历史数据、资源查找、文件记录等功能。 2.实例 数据库中&#xff0c;表的名称、表字段名、其他相关的描述信息&a…...

阿里云cdn怎样设置图片压缩

阿里云 CDN 提供了图像加速服务&#xff0c;其中包括图像压缩功能。通过设置图片压缩&#xff0c;可以显著减小图片文件的体积&#xff0c;提升网站加载速度&#xff0c;同时减少带宽消耗。九河云来告诉你如何进行图片压缩吧。 如何设置阿里云 CDN 图片压缩&#xff1f; 1. 登…...

白话文实战Nacos(保姆级教程)

前言 上一篇博客 我们创建好了微服务项目,本篇博客来体验一下Nacos作为注册中心和配置中心的功能。 注册中心 如果我们启动了一个Nacos注册中心,那么微服务比如订单服务,启动后就可以连上注册中心把自己注册上去,这过程就是服务注册。每个微服务,比如商品服务都应该注册…...

7. 基于DeepSeek和智谱清言实现RAG问答

课件链接&#xff1a;https://cloud.189.cn/t/VNvmyimY7Vna&#xff08;访问码&#xff1a;e4cb&#xff09;天翼云盘是中国电信推出的云存储服务&#xff0c;为用户提供跨平台的文件存储、备份、同步及分享服务&#xff0c;是国内领先的免费网盘&#xff0c;安全、可靠、稳定、…...

【数据结构】双向链表(真正的零基础)

链表是一种物理存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过指针的链接来实现的&#xff01;在上篇我们学习了单向链表&#xff0c;而单向链表虽然空间利用率高&#xff0c;插入和删除也只需改变指针就可以达到&#xff01;但是我们在每次查找、删除、访问..…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...