React 从零到高级 01-JSX基础(建议从Vue转React 同学一定要详细阅读)

123 阅读4分钟

React 简介和特点

用于构建用户界面的 JavaScript 库;

声明式编程

  1. 声明式编程是目前整个大前端开发的模式:Vue、React、Flutter、SwiftUI;
  2. 它允许我们只需要维护自己的状态,当状态改变时,React可以根据最新的状态去渲染我们的UI界面;

组件化开发

  1. 组件化开发页面目前前端的流行趋势,我们会将复杂的界面拆分成一个个小的组件;
  2. 如何合理的进行组件的划分和设计也是后面我会讲到的一个重点;

多平台适配

  1. 2013年,React发布之初主要是开发Web页面
  2. 2015年,Facebook推出了ReactNative,用于开发移动端跨平台;(虽然目前Flutter非常火爆,但是还是有很多公司在使用 ReactNative)
  3. 2017年,Facebook推出ReactVR,用于开发虚拟现实Web应用程序;(VR也会是一个火爆的应用场景)

React由Facebook来更新和维护,它是大量优秀程序员的思想结晶:

  1. React的流行不仅仅局限于普通开发工程师对它的认可;
  2. 大量流行的其他框架借鉴React的思想;

Vue.js框架设计之初,有很多的灵感来自Angular和React。

  1. 包括Vue3很多新的特性,也是借鉴和学习了React;
  2. 比如React Hooks是开创性的新功能;
  3. Vue Composition API学习了React Hooks的思想;

Flutter的很多灵感都来自React,来自官网的一段话:(SwiftUI呢)

  1. 事实上Flutter中的Widget – Element – RenderObject;
  2. 对应React的就是JSX – 虚拟DOM – 真实DOM;

所以React可以说是前端的先驱者,它总是会引领整个前端的潮流。

组件化中的事件绑定

  • 因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象)
  • 这次因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象;
  • 那么在这里发生监听的时候,react在执行函数时并没有绑定this,默认情况下就是一个undefined;相当于一个默认调用

  <button onClick={this.btn1Click}>按钮1</button>
  通过babel转换后成为
   React.createElement(
                "li",
                {click=btn1Click},
                "\u5217\u8868\u6570\u636E2"
              ),
   所以在按钮调用的时候 就会变成      btn1Click() 默认调用      在react中默认严格模式    foo(); // 默认绑定 => window => 严格模式下 => undefined
      /*
      this的四种绑定规则:
        1.默认绑定 独立执行 foo()
        2.隐式绑定 被一个对象执行 obj.foo() -> obj
        3.显式绑定: call/apply/bind foo.call("aaa") -> String("aaa")
        4.new绑定: new Foo() -> 创建一个新对象, 并且赋值给this
    */
  • 方案一:bind给btnClick显示绑定this
  • 方案二:使用 ES6 class fields 语法
  • 方案三:事件监听时传入箭头函数(个人推荐)
            {/* 1.this绑定方式一: bind绑定 */}
     <button onClick={this.btn1Click.bind(this,'222'}>按钮1</button>

    {/* 2.this绑定方式二: ES6 class fields */}
    
          constructor() {
        super()
        this.btn1Click = this.btn2Click.bind(this)
      }
    <button onClick={this.btn2Click}>按钮2</button>


    {/* 3.this绑定方式三: 直接传入一个箭头函数(重要) */}
evnet可以做一些事 比如 阻止点击默认事件
    <button onClick={(event) => this.btn3Click(evnet,'222')}>按钮3</button>

组件化中的属性绑定

     render() {
        const { title, imgURL, href, isActive, objStyle } = this.state
        // 需求: isActive: true -> active
        // 1.class绑定的写法一: 字符串的拼接
        const className = `abc cba ${isActive ? 'active': ''}`
        // 2.class绑定的写法二: 将所有的class放到数组中
        const classList = ["abc", "cba"]
        if (isActive) classList.push("active")
        // 3.class绑定的写法三: 第三方库classnames -> npm install classnames

        return (
          <div>
            { /* 1.基本属性绑定 */ }
            <h2 title={title}>我是h2元素</h2>
            {/*<img src={imgURL} alt=""/>*/}
            <a href={href}>百度一下</a>

            
            { /* 2.绑定class属性: 最好使用className */ }
            <h2 className={className}>哈哈哈哈</h2>
            <h2 className={classList.join(" ")}>哈哈哈哈</h2>

            
            { /* 3.绑定style属性: 绑定对象类型 */ }
            <h2 style={{color: "red", fontSize: "30px"}}>呵呵呵呵</h2>
            <h2 style={objStyle}>呵呵呵呵</h2>
          </div>
        )
      }

JSX的本质

JSX 其实就是 React.createElement()然后 创建出来一个 ReactElement对象 最终组成了一个JavaScript的对象树 也就是虚拟DOM

image.png

这样React 整个流程就会变成 JSX-使用babel-通过React.createElement -形成了虚拟DOM -通过document.createElement() 转换成真实DOM

image.png

对标Vue 中解析html过程

Vue中会有大量的template-解析成为AST抽象语法书 -通过render 内部调用了大量的h函数 形成VNode 最后形成一个VnodeTree-真实dom

因为在vue的Template中有很多指令 (v-for v-if)都需要解析。所以底层帮忙做了很多解析的 但是在react 中直接通过Babel来进行转换 所以react会很直观