1. 英文官网: https://reactjs.org/
  2. 中文官网: https://react.docschina.org/

相关js库

  1. react.js:React核心库。
  2. react-dom.js:提供操作DOM的react扩展库。
  3. babel.min.js:解析JSX语法代码转为JS代码的库。

JSX

关于JSX

  1. 全称: JavaScript XML
  2. react定义的一种类似于XML的JS扩展语法: JS + XML本质是

**React.createElement(component, props, ...children)**方法的语法糖

  1. 作用: 用来简化创建虚拟DOM

image.png

  1. 写法:var ele = **<h1>Hello JSX!</h1>**
  2. 注意1:它不是字符串, 也不是HTML/XML标签
  3. 注意2:它最终产生的就是一个JS对象

  4. 标签名任意: HTML标签或其它标签

  5. 标签属性任意: HTML标签属性或其它
  6. babel.js的作用

    1. 浏览器不能直接解析JSX代码, 需要babel转译为纯JS的代码才能运行
    2. 只要用了JSX,都要加上type=”text/babel”, 声明需要babel来处理

      jsx语法规则

  7. 定义虚拟DOM时,不要写引号。

  8. 标签中混入JS表达式时要用{}。
  9. 样式的类名指定不要用class,要用className。
  10. 内联样式,要用style={{key:value}}的形式去写。
  11. 只有一个根标签
  12. 标签必须闭合
  13. 标签首字母

    • 若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错。
    • 若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错。

      为什么要使用JSX

      image.png

      vscode优化jsx

      jsx.png

      虚拟Dom

      关于虚拟Dom

  14. 本质是Object类型的对象(一般对象)

  15. 虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。
  16. 虚拟DOM最终会被React转化为真实DOM,呈现在页面上。

执行过程
image.png
代码演示
每次执行render()时就会进行diff,不代表浏览器中的元素要重新渲染
image.png

渲染虚拟DOM(元素)

  1. 语法: **ReactDOM.render(virtualDOM, containerDOM)**
  2. 作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
  3. 参数说明
    1. 参数一: 纯js或jsx创建的虚拟dom对象
    2. 参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)

注意:

  1. 组件名必须首字母大写
  2. 虚拟DOM元素只能有一个根元素
  3. 虚拟DOM元素必须有结束标签

    github搜索案例相关知识点

  1. 1.设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办。
  2. 2.ES6小知识点:解构赋值+重命名
  3. let obj = {a:{b:1}}
  4. const {a} = obj; //传统解构赋值
  5. const {a:{b}} = obj; //连续解构赋值
  6. const {a:{b:value}} = obj; //连续解构赋值+重命名
  7. 3.消息订阅与发布机制
  8. 1.先订阅,再发布(理解:有一种隔空对话的感觉)
  9. 2.适用于任意组件间通信
  10. 3.要在组件的componentWillUnmount中取消订阅
  11. 4.fetch发送请求(关注分离的设计思想)
  12. try {
  13. const response= await fetch(`/api1/search/users2?q=${keyWord}`)
  14. const data = await response.json()
  15. console.log(data);
  16. } catch (error) {
  17. console.log('请求出错',error);
  18. }

错误边界

理解:

错误边界(Error boundary):用来捕获后代组件错误,渲染出备用页面

特点:

只能捕获后代组件生命周期产生的错误,不能捕获自己组件产生的错误和其他组件在合成事件、定时器中产生的错误
只有在build打包后的环境下才有用

使用方式:

getDerivedStateFromError配合componentDidCatch

// 生命周期函数,一旦后台组件报错,就会触发
static getDerivedStateFromError(error) {
    console.log(error);
    // 在render之前触发
    // 返回新的state
    return {
        hasError: true,
    };
}

componentDidCatch(error, info) {
    // 统计页面的错误。发送请求发送到后台去
    console.log(error, info);
}

render() {
  return (
    <div>
      {this.state.hasError ? <h2>当前网络不稳定,稍后再试</h2> : <Child/>}
        </div>
    )
}

案例代码

父组件

import React, { Component } from 'react'
import Child from './Child'

export default class Parent extends Component {

    state = {
        hasError:'' //用于标识子组件是否产生错误
    }

    //当Parent的子组件出现报错时候,会触发getDerivedStateFromError调用,并携带错误信息
    static getDerivedStateFromError(error){
        console.log('@@@',error);
        return {hasError:error}
    }

    componentDidCatch(){
        console.log('此处统计错误,反馈给服务器,用于通知编码人员进行bug的解决');
    }

    render() {
        return (
            <div>
                <h2>我是Parent组件</h2>
                {this.state.hasError ? <h2>当前网络不稳定,稍后再试</h2> : <Child/>}
            </div>
        )
    }
}

子组件

import React, { Component } from 'react'

export default class Child extends Component {
    state = {
        users:[
            {id:'001',name:'tom',age:18},
            {id:'002',name:'jack',age:19},
            {id:'003',name:'peiqi',age:20},
        ]
        // users:'abc' //修改此处使map报错
    }

    render() {
        return (
            <div>
                <h2>我是Child组件</h2>
                {
                    this.state.users.map((userObj)=>{
                        return <h4 key={userObj.id}>{userObj.name}----{userObj.age}</h4>
                    })
                }
            </div>
        )
    }
}