• React (1)


    一、React概述

    英文官网: https://reactjs.org/
    用于构建用户界面的 JavaScript 库 —— React只涉及到JS,不涉及HTML/CSS;
    由Facebook在2013年5月开源,目前最新稳定版是v18.2。
    特点: ①数据响应式/声明式 ②组件化开发 ③既可以开发Web应用,又可以开发原生App

    项目中使用React的两种方式:
    方式1:脚本引入式,
    方式2:脚手架方式, create-react-app

    二、JSX

    JavaScript XML:是使用XML的语法创建DOM元素的语法 —— 来自于TypeScript,后来被React框架所采用。但是,浏览器不能直接执行TS/JSX代码,必须使用Babel编译器才可以。即:如果React项目没有使用JSX语法,就可以不引入babel.js;反之就必须引入。
    Babel.js:是一个第三方提供的JS编译器,可以把浏览器不认识的 JS 语法转换为浏览器可以认识的JS语法,例如: ES6=>ES5、 TypeScript=>JS
    JSX语法要求:
    ①标签名称任意,大小写任意,但是必须闭合 —— 但是React要求自定义组件名必须使用“大驼峰命名法”;而HTML标签名必须纯小写;
    ②标签可以声明属性,值必须用引号括起来;
    ③一段JSX有且只有一个根元素;
    ④“JSX本质不是HTML而是JS”——JSX会被Babel编译器转化为纯JS:React.createElement(…);
    ⑤JSX编译出来的代码都运行在“严格模式下”——“use strict”;
    ⑥一段JSX严重推荐使用一个()括起来;
    总结:JSX在React项目中用于“在严格模式下,创建虚拟DOM对象”

    三、React中自定义组件

    React中提供了两种创建自定义组件的语法:
    语法1:function式组件 —— 体现的是“面向过程”的编程思想 (C、C++、PHP、JS)

    function 组件名( ){
       return (JSX)
    }
    let vchild = <组件名 />
    

    语法2:class式组件 —— 体现的是“面向对象”的编程思想 (Java、C++、PHP、JS)

    class 组件名  extends  React.Component {     //类 = 属性 + 方法
      render( ){   //重写继承自父类的方法
         return (JSX)
      }
    }
    let vchild = <组件名 />
    

    四、使用React的第二种方式:使用React命令行脚手架

    创建一个Vue.js项目,可以使用脚手架工具:Vue-CLI
    类似的,创建一个React项目,可以使用脚手架工具:Create-React-App
    使用步骤:
    1)必须安装Node.js,且版本号必须 >= V14.0.0
    node -v
    该版本的Node.js提供了三个工具: node.exe、npm.cmd、npx.exe
    2)下载并执行React脚手架工具
    npx create-react-app 项目名
    3)进入项目目录,启动开发服务器
    npm start

    Node.js 安装包提供的工具:npx —— Node Package Executor,Node包执行器
    功能: 如果当前计算机上有后面的命令,则直接执行;否则就立即下载该命令,再执行
    使用方法: npx 包名 使用参数
    

    NPM工具的下载仓库:
    查看NPM当前默认的下载仓库:npm config get registry
    修改NPM默认的下载仓库:npm config set registry 新的仓库地址
    推荐的仓库地址,例如: https://registry.npmmirror.com/

    JS对象字面量语法class中声明成员语法
    centered 文本居中right-aligned 文本居右

    创建自定义组件的两种语法

    面向过程 —— function式组件 —— rfc

    function MfFooter(){
    			return (JSX)
    		} 
    		let  vnode = <MfFooter />
    

    面向对象 —— class式组件 —— rcc

    class MfFooter extends React.Component{
    			f1=function(){  clg(this)  }
    			render(){
    				return (<button onClick={this.f1}></button>)
    			}
    		}
    		let  vnode = <MfFooter/>
    

    五、重点面试题:React中的事件处理

    为什么React 事件处理函数 中的this指向undefined???而普通函数调用中没有此现象。
    ①JS中this指向调用当前方法的对象
    ②React中“事件源对象”不存在,JSX构建的虚拟DOM
    ③JSX编译得到的代码是一段运行于“严格模式”的JS,其中的函数里this指向undefined
    如果函数发生了调用,That指向调用者

    解决方案:

    1. 把事件处理函数声明为箭头函数 f1 = ()=>{ clg(this) }
    2. 在事件处理函数赋值时使用箭头函数 onClick={ ()=>{this.f1(实参)} } 可以给事件处理函数传参
    3. 在指定事件处理函数时使用“固定了this指向的f1副本”—— 多次渲染后会生成多个副本 onClick={ this.f1.bind(this) }
    4. 在指定事件处理函数时使用“固定了this指向的f1副本”—— 此bind操作只执行一次 见下方代码
    constructor(){
       super( )
       this.f1 = this.f1.bind( this )  
        //构造方法中的语句,自动执行且仅执行一次
       }
    onClick={ this.f1 }
    

    (复习JS知识点:this的指向问题)在这里插入图片描述

    (复习:JS高级中的bind函数 —— 返回当前函数的一个副本,
    唯一的区别是其中的this固定指向参数对象)

    let f1 = function(){
       console.log('------------------')
       console.log( this )
       console.log('------------------')
    }
    f1( )
    
    let emp = {ename:'dangdang', age: 20}
    let car = {brand:'奔驰', speed:200}
    
    
    //希望调用f1时,输出的this指向emp
    let  f2 = f1.bind( emp )
    f2( )
    //希望调用f1时,输出的this指向car
    let  f3 = f1.bind( car )
    f3( )
    '
    运行

    (复习JS知识点:class中执行且仅执行一次的方法 —— 构造方法)

    class Parent{
       constructor(){ ... }
    }
    
    class Emp extends Parent{
       constructor( ){
          super( ) //子类体内调用父类构造方法,在子类对象体内创建一个父类对象的实例——继承的本质
          console.log('一个Emp实例被创建出来了')
       }
    }
    let e1 = new Emp( )   //调用构造方法,创建一个对象的实例
    let e2 = new Emp( )   //调用构造方法,创建一个对象的实例
    

    六、重要面试题:Vue.js和React两个框架的区别?

    尤雨溪:Vue.js中的数据响应式是“Push Based(基于推送的)”;而React中的是“Pull Based(基于拉取的)”。

    Vue.js —— Push Based

    data(){
      return  {  age:  10  }
    }
    f1(){
       this.age = 11
       //①修改模型  ②通知渲染系统
    }
    

    小程序 —— Pull Based

    data: {
       age : 10
    }
    f1(){
      this.age = 11  //无效语句
      this.setData({age:11}) //正确
      }
    

    React —— Pull Based

    state = {  //就相当于data
       age: 10 
    }
    f1(){
      this.state.age = 11 //无效语句
      this.setState({age: 11}) //正确
    }
    

    提示:React中的setState()方法是异步的,想查看修改后的值,必须使用其第二个参数:回调函数;且此方法会把修改后的状态变量和没修改的合并起来,而不是覆盖掉。

    在这里插入图片描述

    七、React中的数据绑定

    注意:React中没有“指令”的概念,即无v-on、v-if、v-for、v-model…

    1. 内容绑定:
      {表达式}
    2. 属性绑定:
    3. 样式绑定:
    4. 事件绑定:
    5. 双向数据绑定:
      setXxx(e.target.value)}/>
      (重要面试题:React中如何获取输入框中的内容)
    6. 条件渲染:运用短路逻辑
      { 判定表达式 && (JSX) }
    7. 列表渲染:
      { arr.map( (e,i)=>(JSX) ) }
    重要面试题:React中如何获取输入框中的内容?

    方案1:使用“受控组件”—— 监控用户的每一次输入

    Model:let [kw, setKw]  = useState("戴尔")
    View: <input  value={kw}  onChange={ e=>setKw(e.target.value) }/>
    
    //方向1的绑定:Model=>View
    //方向2的绑定:View=>Model
    

    方案2:使用“非受控组件”—— 无需监控用户的每次输入动作,只需要在最后提交时读取其中的输入

    <input  ref={ }/>
    <button onClick={通过ref查找输入值}>提交</button>
    

    八、class组件的生命周期方法

    React中class是生命周期方法分为三个阶段:(比vue少一个创建阶段)
    挂载阶段:
    constructor( ):构造方法
    render( ):渲染内容
    componentDidMount( ):组件完成挂载,等价于之前的mounted、onLoad
    更新阶段:
    shouldComponentUpdate( ):此次修改需要让组件更新吗?需要返回true或false 提供两个参数监听数据变化
    render( ):渲染内容
    componentDidUpdate( ):组件完成更新
    卸载阶段:
    componentWillUnmount( ):组件即将卸载,等价于之前的destroyed、onUnload

    九、重要知识点:React Hooks

    早期的React提供了function组件和class组件两种方式;但是function组件功能太弱了:

    • 没有state和setState() —— 不继承React.Component类
    • 没有任何生命周期方法 —— 不继承React.Component类

    React V16.8,官方为function式组件提供了新功能:Hooks,弥补了之前的不足,再加上本身天然优势(天然就没有this),导致function式组件“异常强大”。官方提供了15个钩子函数

    Hook:钩子,本身就是一个普通的函数,用于为function式组件“钩住”更多的功能——例如:状态、生命周期方法…所有的钩子函数有如下特性:

    1. Hook函数只能在function组件中使用,不能用于class组件;
    2. 所有的Hook函数都必须以use-开头,例如:useState( )、useEffect( )、…;
    3. Hook函数只能在组件的最外层使用,不能在内层
    function  XzFooter(){
       useState()  合法
       if(){ useState() 非法 }
       for(*){ useState() 非法 }
       function(){ useState() 非法}
    }
    

    十、React官方提供的常用Hook

    1. useState( )状态钩子 —— 为函数式组件添加state和setState( )方法
      import {useState} from 'react'
      let [ 变量名, 方法名 ] = useState( 初始值 ) //[ 初始值, func ]
    2. useEffect( )副作用钩子—— 为函数式组件添加“副作用(即生命周期方法)”
      import {useEffect} from 'react'

    function式组件生命周期方法1:

    useEffect( ( )=>{ 
       //生命周期方法1 = 组件完成挂载 + 任意状态数据发生改变
    } )
    

    function式组件生命周期方法2:

    useEffect( ( )=>{
       //生命周期方法2 = 组件完成挂载 + 指定的状态变量发生改变
    }, [变量1, 变量2, ...] )   //有依赖列表
    

    function式组件生命周期方法3:

    useEffect( ( )=>{
       //生命周期方法3 = 组件完成挂载     //等价于之前的mounted、onLoad
    }, [ ] )   //空依赖
    

    function式组件生命周期方法4:

    useEffect( ( )=>{
       return ( )=>{ 
           //生命周期方法4 = 任意的状态数据发生改变 + 组件卸载
       }
    } )
    

    function式组件生命周期方法5:

    useEffect( ( )=>{
       return ( )=>{
            //生命周期方法5 = 依赖的状态数据发生改变 + 组件即将卸载
       }
    }, [变量1, 变量2,....] )  //有依赖列表
    

    function式组件生命周期方法6:

    useEffect( ()=>{
       return ()=>{
           //生命周期方法6 = 组件即将卸载
       }
    }, [ ] )  //空依赖
    
    1. useRef( )元素引用钩子
  • 相关阅读:
    Kotlin高仿微信-第22篇-个人信息-修改昵称
    温度对免疫代谢调节和癌症进展的影响
    牛客网刷题(四)
    聚观早报 | 遥感AI大模型发布;拼多多启动11.11大促
    RTMP协议详解及Wiresahrk抓包分析
    Kibana Discover数据查询
    (附源码)计算机毕业设计Java巴州监控中心人事管理系统
    RocketMQ 5.0 vs 4.9.X 图解架构对比
    看完这篇 教你玩转渗透测试靶机vulnhub——FunBox3(Easy)
    抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。抖音矩阵系统。
  • 原文地址:https://blog.csdn.net/m0_70328115/article/details/127097946