react学习笔记
1、react在前端中的地位
官网:https://zh-hans.react.dev/learn
react是什么:用于构建 Web 和原生交互界面的库
2、邂逅react开发
- 声明式编程
- 组件化开发
- 跨平台编写
声明式编程:声明式编程是目前整个大前端开发的模式:Vue、React、Flutter、SwiftUI;它允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面;

组件化开发:组件化开发页面目前前端的流行趋势,我们会将复杂的界面拆分成一个个小的组件;
多平台适配:2013年,React发布之初主要是开发Web页面;2015年,Facebook推出了ReactNative,用于开发移动端跨平台;2017年,Facebook推出ReactVR,用于开发虚拟现实Web应用程序;
react的开发依赖:开发React必须依赖三个库:
- react:包含react所必须的核心代码
- react-dom:react渲染在不同平台所需要的核心代码
- babel:将jsx转换成React代码的工具
Babel和React的关系:
babel是什么:Babel ,又名 Babel.js。 是目前前端使用非常广泛的编译器、转移器。 比如当下很多浏览器并不支持ES6的语法,但是确实ES6的语法非常的简洁和方便,我们开发时希望使用它。 那么编写源码时我们就可以使用ES6来编写,之后通过Babel工具,将ES6转成大多数浏览器都支持的ES5的语法。
React和Babel的关系:默认情况下开发React其实可以不使用babel。 但是前提是我们自己使用 React.createElement 来编写源代码,它编写的代码非常的繁琐和可读性差。 那么我们就可以直接编写jsx(JavaScript XML)的语法,并且让babel帮助我们转换成React.createElement。
Hello Word
第一步:在界面上通过React显示一个Hello World
注意:这里我们编写React的script代码中,必须添加 type="text/babel",作用是可以让babel解析jsx的语法

ReactDOM. createRoot函数:用于创建一个React根,之后渲染的内容会包含在这个根中 。参数:将渲染的内容,挂载到哪一个HTML元素上 。这里我们已经提定义一个id为app的div root.render函数: 参数:要渲染的根组件 。我们可以通过{}语法来引入外部的变量或者表达式
Hello React – 组件化开发
整个逻辑其实可以看做一个整体,那么我们就可以将其封装成一个组件。我们说过root.render 参数是一个HTML元素或者一个组件;所以我们可以先将之前的业务逻辑封装到一个组件中,然后传入到 ReactDOM.render 函数中的第一个参数;
在React中,如何封装一个组件呢?这里我们暂时使用类的方式封装组件
定义一个类(类名大写,组件的名称是必须大写的,小写会被认为是HTML元素),继承自React.Component 。2.实现当前组件的render函数 ✓ render当中返回的jsx内容,就是之后React会帮助我们渲染的内容

组件化---数据依赖
在组件中的数据,我们可以分成两类:
- 参与界面更新的数据:当数据变量时,需要更新组件渲染的内容;
- 不参与界面更新的数据:当数据变量时,不需要更新将组建渲染的内容;
参与界面更新的数据我们也可以称之为是参与数据流,这个数据是定义在当前对象的state中
我们可以通过在构造函数中 this.state = {定义的数据}
我们的数据发生变化时,我们可以调用 this.setState 来更新数据,并且通知React进行update操作; ✓ 在进行update操作时,就会重新调用render函数,并且使用最新的数据,来渲染界面

组件化---事件绑定
组件化问题二:事件绑定中的this 。
在类中直接定义一个函数,并且将这个函数绑定到元素的onClick事件上,当前这个函数的this指向的是谁呢? 默认情况下是undefined 。 很奇怪,居然是undefined; 因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象); 因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象; 那么在这里发生监听的时候,react在执行函数时并没有绑定this,默认情况下就是一个undefined; 我们在绑定的函数中,可能想要使用当前对象,比如执行 this.setState 函数,就必须拿到当前对象的this 。我们就需要在传入函数时,给这个函数直接绑定this 类似于下面的写法:

3、react的jsx语法解析
JSX是什么? JSX是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法; 它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用; 它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
React认为渲染逻辑本质上与其他UI逻辑存在内在耦合 。比如UI需要绑定事件(button、a原生等等); 比如UI中需要展示数据状态; 比如在某些状态发生改变时,又需要改变UI; 他们之间是密不可分,所以React没有将标记分离到不同的文件中,而是将它们组合到了一起,这个地方就是组件(Component); 当然,后面我们还是会继续学习更多组件相关的东西; 在这里,我们只需要知道,JSX其实是嵌入到JavaScript中的一种结构语法; JSX的书写规范: JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个div元素(或者使用后面我们学习的Fragment); 为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写; JSX中的标签可以是单标签,也可以是双标签; ✓ 注意:如果是单标签,必须以/>结尾;
jsx中的注释 。JSX嵌入变量作为子元素 。
情况一:当变量是Number、String、Array类型时,可以直接显示 。
情况二:当变量是null、undefined、Boolean类型时,内容为空; ✓ 如果希望可以显示null、undefined、Boolean,那么需要转成字符串; ✓ 转换的方式有很多,比如toString方法、和空字符串拼接,String(变量)等方式;
情况三:Object对象类型不能作为子元素(not valid as a React child) 。 JSX嵌入表达式 、 运算表达式 、三元运算符 、 执行一个函数
react事件绑定
如果原生DOM原生有一个监听事件,我们可以如何操作呢? 方式一:获取DOM原生,添加监听事件; 方式二:在HTML原生中,直接绑定onclick;
在React中是如何操作呢?我们来实现一下React中的事件监听,这里主要有两点不同
- React 事件的命名采用小驼峰式(camelCase),而不是纯小写;
- 我们需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行;
this的绑定问题
在事件执行后,我们可能需要获取当前类的对象中相关的属性,这个时候需要用到this 。
如果我们这里直接打印this,也会发现它是一个undefined 。为什么是undefined呢?
原因是btnClick函数并不是我们主动调用的,而且当button发生改变时,React内部调用了btnClick函数; 而它内部调用时,并不知道要如何绑定正确的this;
如何解决this的问题呢?
- bind给btnClick显示绑定this
- 使用 ES6 class fields 语法
- 事件监听时传入箭头函数(个人推荐)
方法一:事件函数定义为箭头函数并返回一个函数
1 import React, {PureComponent} from 'react'; 2 class UseThis extends PureComponent { 3 btnClickHandle = (params) => { 4 return (e) => { 5 console.log(this) 6 console.log(params) 7 console.log(e) 8 } 9 } 10 11 render() { 12 return ( 13 <div> 14 <button onClick={this.btnClickHandle("琉球")}>点击</button> 15 </div> 16 ); 17 } 18 } 19 export default UseThis;

方法二:使用bind绑定this
1 import React, {PureComponent} from 'react'; 2 3 class UseThis extends PureComponent {11 12 btnClickHandle2(params, e) { 13 console.log(this) 14 console.log(e) 15 console.log(params) 16 } 17 18 render() { 19 return ( 20 <div> 22 <button onClick={this.btnClickHandle2.bind(this, "朝鲜")}>点击2</button> 23 </div> 24 ); 25 } 26 } 27 28 export default UseThis;
方法三:事件监听时传入箭头函数
1 import React, {PureComponent} from 'react'; 2 3 class UseThis extends PureComponent { 4 btnClickHandle3(e,params){ 5 console.log(this) 6 console.log(e) 7 console.log(params) 8 } 9 render() { 10 return ( 11 <div> 12 <button onClick={e=>{this.btnClickHandle3(e,"韩国")}}>点击3</button> 13 </div> 14 ); 15 } 16 } 17 18 export default UseThis;
react条件渲染
某些情况下,界面的内容会根据不同的情况显示不同的内容,或者决定是否渲染某部分内容: 在vue中,我们会通过指令来控制:比如v-if、v-show; 在React中,所有的条件判断都和普通的JavaScript代码一致;
常见的条件渲染的方式有哪些呢?
◼ 方式一:条件判断语句 ;适合逻辑较多的情况
◼ 方式二:三元运算符 ;适合逻辑比较简单
◼ 方式三:与运算符&& ;适合如果条件成立,渲染某一个组件;如果条件不成立,什么内容也不渲染;
◼ v-show的效果 主要是控制display属性是否为none。
react列表渲染
在React中,展示列表最多的方式就是使用数组的map高阶函数;
列表中的key
key主要的作用是为了提高diff算法时的效率;
jsx的本质
实际上,jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖。 所有的jsx最终都会被转换成React.createElement的函数调用。
createElement需要传递三个参数:
- type;当前ReactElement的类型; 如果是标签元素,那么就使用字符串表示 “div”; 如果是组件元素,那么就直接使用组件的名称;
- config ;所有jsx中的属性都在config中以对象的属性和值的形式存储; 比如传入className作为元素的class;
- 参数三:children ; 存放在标签中的内容,以children数组的方式进行存储; 当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方

我们自己来编写React.createElement代码:
我们就没有通过jsx来书写了,界面依然是可以正常的渲染。
另外,在这样的情况下,你还需要babel相关的内容吗?不需要了 ✓
所以,type="text/babel"可以被我们删除掉了;

虚拟DOM的创建过程
我们通过 React.createElement 最终创建出来一个 ReactElement对象:

◼这个ReactElement对象是什么作用呢?React为什么要创建它呢?
原因是React利用ReactElement对象组成了一个JavaScript的对象树; JavaScript的对象树就是虚拟DOM(Virtual DOM);

◼ 如何查看ReactElement的树结构呢? 我们可以将之前的jsx返回结果进行打印; 注意下面代码中我打jsx的打印; ◼ 而ReactElement最终形成的树结构就是Virtual DOM;

虚拟DOM帮助我们从命令式编程转到了声明式编程的模式 ◼
React官方的说法:Virtual DOM 是一种编程理念。
在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象 。我们可以通过ReactDOM.render让 虚拟DOM 和 真实DOM同步起来,这个过程中叫做协调(Reconciliation);
这种编程的方式赋予了React声明式的API: 你只需要告诉React希望让UI是什么状态; React来确保DOM和这些状态是匹配的; 你不需要直接进行DOM操作,就可以从手动更改DOM、属性操作、事件处理中解放出来;
4、react脚手架解析
对于现在比较流行的三大框架都有属于自己的脚手架: Vue的脚手架:@vue/cli ;Angular的脚手架:@angular/cli; React的脚手架:create-react-app
它们的作用都是帮助我们生成一个通用的目录结构,并且已经将我们所需的工程环境配置好。 使用这些脚手架需要依赖什么呢? 目前这些脚手架都是使用node编写的,并且都是基于webpack的; 所以我们必须在自己的电脑上安装node环境;
这里我们主要是学习React,所以我们以React的脚手架工具:create-react-app作为讲解;

5、react组件化开发