react复习笔记一

发布于:2025-03-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

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被称为单向数据驱动的框架

2. 关于版本问题
  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(区块链)
    + ...

3. 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>
  .....


=================================
4. 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),计算出差异的部分,最后只把差异的部分进行更新!

5. 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是弱编程性的语法),构建视图更加的灵活方便!!


网站公告

今日签到

点亮在社区的每一天
去签到