React (1)

一、React概述

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

项目中使用React的两种方式:
方式1:脚本引入式, <script src="react.js"></script>
方式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. 内容绑定:
    <any>{表达式}</any>
  2. 属性绑定:
    <any 属性名={表达式}/>
  3. 样式绑定:
    <any style={ {color:'red'} }/>
  4. 事件绑定:
    <any onClick={表达式}/>
  5. 双向数据绑定:
    <input value={表达式} onChange={e=>setXxx(e.target.value)}/>
    (重要面试题:React中如何获取输入框中的内容)
  6. 条件渲染:运用短路逻辑
    <any>{ 判定表达式 && (JSX) }</any>
  7. 列表渲染:
    <any>{ arr.map( (e,i)=>(JSX) ) }</any>
重要面试题: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( )元素引用钩子
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值