Visual LabINTERACTIVE LEARNING
框架原理第 1 / 7 章

React 基础与组件模型

从版本、JSX 和脚手架进入组件化与高级组件开发。

React组件Redux
进阶预计 58 分钟查看源文 ↗

react的特点

  • 声明式 UI= f(state),只需要维护数据,UI会自动被更新
  • 组件化 拆分成不同颗粒度的组件
  • 跨平台 虚拟dom,编译到不同的平台】

React 版本区别

  1. api区别
const el= document.querySelector("root")

//18之前,
reactDOM.render(<div>hello world</div>,el)
//18 之后
const root = reactDOM.createRoot(el)
root.render(<div>hello world</div>)

类组件

  • 类组件继承自React.Component,初始化时要super去调用一下父组件的构造方法
  • 在构造函数中使用 this.state 对象中去定义参与UI更新的数据
  • 方法绑定,this问题 类方法中的this绑定,会变成undefined

class App extends React.Component {
  constructor(){
    super()
    this.state = {
      message = "hello world"
    }
    // 方法一trick 在构造函数统一绑定this
   // this.btnClick = this.btnClick.bind(this)
  }
   // 方法一 定义类方法,然后使用的时候绑定this
   btnClick(){
   //这里的this是不一定就是当前的类,取决于其调用方式,
   //如果作为一个回调函数给别的函数调用,由于它是类方法,默认开启严格模式,this的值是undefined
   // 所以需要绑定this
    console.log(this)
   }
   // 方法二 箭头函数 默认绑定的是定义时的this,也就是当前实例,这个是类的字段
   // btnClick = ()=>{
   //  console.log(this)
   //}
   
   //方法三 事件监听时去定义一个箭头函数
  
  render(){
    
    return (
    <div>
      <h2>{message}</h2>
      
      <button onClick={this.btnClick.bind(this)}></button>
      // {/* 方法三 事件监听时去定义一个箭头函数 */}
      <button onClick={ (e)=> this.btnClick(e)}></button>
    </div>
    )
  }

}

jsx语法

  1. jsx基本语法

🍰 提示

jsx是js扩展语法,允许在js里面书写html代码,html in js,把UI界面的描述融合到js中 为什么react选择了jsx? UI和数据逻辑的耦合度非常高,状态和UI密不可分,所以干脆融合一起

  1. jsx规范
  • 顶层只有一个根元素
  • 外层用小括号包裹,实现内容换行,提高可读性
  • 单标签使用/结尾
  1. jsx注释, 使用{}内多行注释的方式
 <div>
   {/*v这是注释 */}
 </div>
  1. jsx插入内容(标签的children,不是属性)
  <div>
   {/*基本类型字符串、数字、数组、会直接显示 出来*/}
   { }
 </div>
 <div>
   {/*undefined、null、Boolean 类型会被忽略(即使是true)*/}
   { }
 </div>
 <div>
   {/*对象类型不能作为子对象,会直接报错*/}
   { }
 </div>
// 表达式、运算符、函数调用都是合法的
  1. jsx的属性绑定
  • 使用{}进行绑定
  • 绑定class,使用关键词className
  • 属性中支持绑定一个对象,如style中可以使用一个对象来实现不同的样式绑定

脚手架

组件化开发

🏝️ 提示

把大的模块拆分细化成一系列小的组件,分而治之,最终通过组合实现大的模块的功能 函数组件 (Functional Component) 类组件 (Class Component)

  1. 类组件
  • 组件名称大写字母开头

  • 类组件需要继承自React.Component

  • 类组件必须实现render函数

  • constructor是可选的,如果有状态需要维护则需要定义this.state对象,使用this.setState方法更新

  • render函数必须实现,首次渲染以及this.state 或this.props改变时被执行,它可以返回:

    1. React元素

    2. 返回一个数组或fragments

    3. 字符串或者数值

  1. 函数组件
  • 函数组件没有生命周期
  • this不能指向组件实例
  • 内部没法保存状态
  1. 生命周期
  • Mount componetDidMount
  • Update componetDidUpdate
  • Unmount componetWillUnmount

复杂版,should

  1. 组件间通信,实现方式多样

🎼 提示

  1. 直接通过属性来通信,子组件通过props来获取,父组件传递一个回调函数给子组件,子组件执行则实现了子组件给父组件传递数据
  1. 插槽

🍰 提示

  1. 通过this.props.children来获取传进去的子组件,多个时是数组,单个时就是子组件本身
  2. 直接通过this.props 的具体属性来传递
  3. 作用域插槽 --> 使用一个回调函数来作为组件,子组件使用时传入参数
  1. 非父子通信

🥖 提示

Context 上下文共享 Context.Consumer 可以在函数组件中使用,也可以在类组件中使用,且多个上下文需要·

  1. setState

🏖️ 提示

  1. 第一个参数可以是对象,也可以是函数,函数则会回传(state,props)两个参数,可以处理一些逻辑(如递增的情况,需要用这个state,不一定和this.state相同,取决于有没有更新完成),函数要返回一个state对象
  2. setState是一个异步调用,调用后不会立即执行state合并,设计成异步的原因是1. 合并多个更新再去调用render,保持state和props的一致性
  3. setState第二个参数是合并后的回调,确保this.state的新的数据

高级组件开发

🎉 提示

class Component使用 pureComponent,内部已经使用shallowEqual比较state和props的浅层是否相同,相同则不更新,不相同则更新 Functional Component则使用 memo去包裹