react复习笔记一

  1. MVVM(Vue) VS MVC(React)

MVVM:Model View viewModel 双向数据驱动

MVC:Model View Controller 单向数据驱动

Model:数据层

View:视图层

Controller:控制层

  • 我们要学会如何构建数据/状态,以及修改状态的方法「例如:setState、useState...」

  • 当我们基于特定的方法修改状态后,会通知视图更新

-----> React的MVC框架中,实现了 "数据驱动视图渲染「M->V」"

  • 我们要学会如何构建视图

Vue中是基于 <template>(主) / jsx 语法构建视图的

React中构建视图的语法是:jsx

-----> 不论是Vue还是React,构建的视图都有一套编译机制:VirtualDOM(虚拟DOM)-> DOM-DIFF -> 真实DOM

  • 如果视图中的表单元素内容发生改变

Vue基于v-model指令自动监听表单内容的变化,而后把对应的状态值进行自动更改,所以Vue是双向驱动的框架,"视图驱动数据更新「V->M」"

React默认没有实现视图驱动数据,需要开发者手动对表单元素进行事件绑定和监听,手动去修改对应的状态,所以React被称为单向数据驱动的框架

  1. 关于版本问题

Vue框架「@vue/cli、vite」

  • Vue2、Vuex3、VueRouter3、ElementUI或Antdv1或vant2或iview 「用的最多」

  • Vue3、Vuex4(Pinia)、VueRouter4、ElementPlus或者Antdv或vant3、TypeScript 「新的趋势」

React框架

  • create-react-app(vite)、React16/18、redux(或mobx、zustand)、react-router-dom5/6、Antd或AntdMobile、TypeScript

  • 淘系React方案:umi、antdpro「核心 redux/redux-saga、react-router-dom5、dva」

小程序开发

  • 原生小程序开发

  • Vue:uni-app

  • React:taro

NativeApp开发

  • Vue:uni-app

  • React:react-native

  • flutter「Dart语言」

项目应用级体系

  • Node、Express(或Koa2、Egg)、Mongodb(或MySQl、SQLServer...)、Linux(Nginx、Docker)、nuxt.js/next.js「SSR渲染」...

  • 微前端

  • 低代码

  • 可视化「canvas、webGL(three.js)...」

  • Web3(区块链)

  • ...

  1. jsx语法

jsx:javascript and xml(html)

为了让vscode支持jsx语法「有提示、可以格式化等」,我们把需要构建视图的js文件,其后缀名改为 .jsx

  • 我们可以把每一个 .jsx 理解为一个单文件组件(可以构建视图)

  • .jsx 的文件,在webpack打包的时候,也是按照js的方式处理


把所有的视图(内容)编译后,都放在#root的容器中渲染「React18」

const root = ReactDOM.createRoot(document.getElementById('root'))

root.render(

<div>

珠峰培训

</div>

)

在React16中,这部分是这样操作的

ReactDOM.render(

<div>

珠峰培训

</div>,

document.getElementById('root')

)


@1 在JSX语法中,我们基于 "{}" (大)胡子语法绑定JS表达式

JS表达式:执行有结果(返回值)的操作

  • 变量 {title}

  • 值 {'哈哈哈'}

  • 数学运算 {1+1}

  • 判断操作 {1===1?'ok':'no'} 只能使用三元运算符「if/else、switch/case不算表达式」

  • 循环操作 for、while、for in等循环,不算JS表达式

{

arr.map((item,index)=>{

return <li key={index}> //循环创建的元素,要设置唯一的key属性值

{item}

</li>

})

}

  • ...

在胡子语法中,嵌入不同数据类型的值,最后渲染的结果是不同的

  • 原始值类型中:除了 数字、字符串 会直接渲染出来,其余的值,最后渲染的结果都是空

  • 对象数据类型:

数组对象:不会转字符串,而是内部,会把数组中的每一项都单独拿出来渲染

函数对象:期望我们是基于 <Component> 这种方式调用函数组件

剩下的大部分对象,是不允许直接在 胡子语法 中渲染的!「排除:给元素设置style行内样式;如果对象是JSX元素对象(VirtualDOM),是可以直接渲染的」

@2 给元素/组件设置属性

  • 如果属性值是一个字符串,直接正常设置即可

  • 其余情况(例如:把变量的值作为属性值、或者传递的属性值是其它类型的),此时基于 "{}" 嵌套绑定即可

  • 特殊1:给元素设置的class要改为className

  • 特殊2:给元素设置的style,要求其属性值必须是一个对象

let num = 10

<Component name="box" x={num} y={0} className="box" style={样式对象}/>

@3 每个视图(无论大或者小),都只能设置一个根节点

  • 基于map循环的时候,每一轮循环产生的上下文,算是一个小的视图,也不允许出现多个根节点

  • 如果即想让其只有一个根节点,也想让包起来的外层盒子不占据层级结构,可以使用 <></> 「React.Fragment」

@4 基于胡子语法渲染的内容,都被当做普通字符串进行渲染,无法识别其内部的HTML标签(类似于v-text);现如今我们期望可以把字符串中的标签自动识别,就需要用到:

<div dangerouslySetInnerHTML={{

__html: str

}}></div>

@5 JSX中的事件绑定,是基于React内部的合成事件处理的「onXxx」

<div onClick={ev=>{

//.....

}}></div>

.....

=================================

  1. jsx的底层渲染机制

@1 基于 babel-preset-react-app 语法包,把jsx编译为 React.createElement 这种格式

凡是HTML标签(或组件),都会被编译为createElement这种格式!!

React.createElement(

标签名/组件名,

属性对象/null, //->存储了给标签设置的各种各样的属性

后续参数都是其子节点

)

@2 把 createElement 方法执行,创建出对应的 VirtualDOM(虚拟DOM对象) 「也被成为:JSX元素对象」

虚拟DOM:框架内部自己构建的一个对象,用来描述和记录元素标签的相关特征

真实DOM:交给浏览器渲染的、或者是渲染完毕后看到的元素标签、再或者是基于JS获取到的原生DOM对象(有浏览器内置的属性和方法)

VirtualDOM = {

$$typeof: Symbol(react.element), //标识

type: "div", //标签名或者组件

key: "10",

ref: "AAA",

props: {

除key/ref外其它设置的属性,

children:子节点集合「可能没有、可能是一个值、可能是一个数组」

}

}

@3 基于 render 方法,把创建的 VirtualDOM 渲染为真实的DOM

总结:React视图编译的机制

@1 把 jsx 语法,基于 babel-preset-react-app & React.createElement 创建出相应的 VirtualDOM

@2 如果是第一次渲染视图,直接基于 render 方法,把 VirtualDOM 变为 真实DOM「并且把本次创建的VirtualDOM缓存起来」

@3 当视图更新的时候,会重新的按照最新的数据,把 jsx 编译为一个全新的 VirtualDOM,并且用 新的VirtualDOM 和之前 旧的VirtualDOM 进行对比(DOM-DIFF),计算出差异的部分,最后只把差异的部分进行更新!

  1. jsx VS <template>

Vue2/Vue3中,既有 <template> 语法,也支持 jsx 语法

React中只有 jsx 语法


state/data = {

flag:true,

arr:...,

text:'...',

level:2

}

<template>

<div class="box">

<button v-if="flag">{{text}}</button>

<span v-for="item in arr" :key="item.id">

{{item.title}}

</span>

<h1 v-if="level===1">我是标题</h1>

<h2 v-else-if="level===2">我是标题</h2>

<h3 v-else-if="level===3">我是标题</h3>

</div>

</template>

<div className="box">

{flag?<button>{text}</button>:null}

{arr.map(item=>{

return <span key={item.id}>

{item.title}

</span>

})}

{React.createElement(`h${level}`,null,'我是标题')}

</div>

JSX语法比<template>语法具备更强的编程性(或者template是弱编程性的语法),构建视图更加的灵活方便!!

相关推荐
kyriewen9 小时前
我手写了一个 EventEmitter,面试官追问了 6 个问题——第 4 个我没答上来
前端·javascript·面试
IT_陈寒9 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
小林攻城狮10 小时前
使用 Transport 节流解决 Vercel AI SDK 流式渲染卡死问题
前端·react.js
前端缘梦10 小时前
告别 TS 运行时类型漏洞!Zod 完整入门实战教程(前端 / 全栈必备)
前端·react.js·全栈
the_answer10 小时前
Webpack vs Vite 深度对比分析
前端·webpack
转转技术团队11 小时前
验证码识别实战:前端不写页面,改训模型了?
前端
MomentYY11 小时前
Temperature:AI 的“脑洞旋钮”
前端·llm·ai编程
远航_11 小时前
OpenSpec 完整详细介绍
前端·后端
召钱熏11 小时前
状态枚举正确≠渲染正确:一个语音按钮的状态机边界修复实录
android·前端
SkyWalking中文站11 小时前
认识 Horizon UI · 1/17:SkyWalking 新一代可观测性控制台
运维·前端·监控