React 入门文档的梳理

React 工具链

根据官网了解到,React既有以下工具链:

Node.js构建服务端渲染网站,可使用Next.js
面向内容的静态网站,可使用Gatsby
以及更灵活的Neutrino、Parcel、Razzle

目前对React还不够熟练,因此现以简单了解为主。

React 元素渲染

元素是React应用的最小单位。
React元素一经创建就是不可变的(immutable),更新的唯一方法是重新创建元素并渲染;
尽管如此,React DOM会将当前元素与之前的进行比较,只做必要的更新。(重要且深刻)

React 组件

设计目标:独立、可复用
React组件有两种形式:

  • 函数组件:
    一个接收props作为参数的纯函数,且return一个React元素;

纯函数不改变自己的传入参数,React组件必须保证props不被修改

  • class组件:
    用ES6的class定义的组件,继承自React.Component;
    两者特性的比较:
    class组件具有状态、生命周期方法等多种特性;
    function组件适用于最新的React Hooks

State 和 setState()

要使用this.setState()方法来改变组件的state,也只有调用setState()修改state,组件才会重新渲染

setState() 是异步的

为了提升性能,React会合并多次setState()请求,因此不能保证对state的改变会立即生效(批量推迟更新);
目前,在事件处理函数的内部,setState()是异步的,这种机制让应用的性能得到提升。

每次更新this.state都必然要调用一轮Update阶段的生命周期函数,这是存在性能消耗的,异步调用setState()就是为了将多次setState()的改变合并在一起,然后一次性更新state,节约性能。

但问题在哪呢?
实际我们经常会基于当前的this.state来更新state,但是this.state可能没有被更新,
这就会导致基于上一个state更新state的操作出现问题。可以参考下面的解决方法:

给setState()传递其他参数

setState(updater, [callback])
updater:
(state, props) => {}
这里的state、props不同于this.state、this.props,它们保证是最新的,可以以此为基础,
更新this.state。该函数最后要返回一个对象,它会被浅层合并到最新的state中。
callback:
可传入回调函数,它在setState完成合并、重新渲染后触发,但也因此可以在componentDidUpdate()上实现一样的效果;

React 生命周期

React生命周期的速查表
https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

React生命周期方法是由React主动调用的

render()是唯一一个必须被实现的生命周期方法

挂载:
constructor()
getDerivedStateFromProps() - 不常用
render()

  • 更新DOM和Refs
    componentDidMount()

更新:
shouldComponentUpdate() - 性能优化
getDerivedStateFromProps() - 不常用

  • 更新DOM和Refs
    componentDidUpdate()

卸载:
componentWillUnmount()

记录:

不要在componentDidMount()之前访问真实的DOM

比如在此之前对refs进行操作,会导致错误

可以使用shouldComponentUpdate()来节约性能

以下是一个例子:

shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

shouldComponentUpdate接受了两个参数,在这仅当“未来的”props||state不等于本来的时候,
才返回true、更新组件,从而当state、props发生改变而改变后值与原来相同时不进行重新渲染,
节省了性能。

shouldComponentUpdate()性能优化的替代方案:

React.PureComponent
它通过浅层比较props和state对象,实现了上述功能。
由于仅做浅层比较,因此不能检查深层的差别(比如做了某个数组中的push操作等)。

浅层比较带来的问题:
还记得const吗?const只保证一个变量其内存指向是不变的,如果改变了对象内部的属性,const也将无能为力,
因此const是浅层的“常量”;
在这里,PureComponent会有一样的情况,如果state、props中的某个属性是对象,那么只要它们的指向不变,
就不会引起组件的更新,从而导致问题。

PureComponent 结合 immutable.js
由于浅层比较只比较了指向,那么 immutable.js 就可以解决这个问题:
这是因为针对immutable对象的一切改变都将返回一个不同的指针,从而得以触发组件的更新。

单向数据流

React的数据是向下流动的,数据只能从父组件流向子组件;
父组件把state传给它的子组件,子组件在props中接收到数据;
但是,子组件要改变父组件的数据,只能调用父组件传入的方法*(下面马上提到),
父组件state修改后,子组件的props随着改变。

React 事件处理

区别:

  1. 事件处理程序的名称不同,React采用驼峰命名而不是纯小写
  2. 直接传入一个回调函数,而不是字符串
  3. 为每个事件处理函数传入了一个符合W3C规范的event,即事件对象,无需关注兼容性问题 (参考DOM3级event对象)
  4. class组件中事件处理函数要绑定this对象,这个过程建议统一写在constructor中!
    (每次render()都执行一次绑定会耗费性能)
  5. 向事件处理函数中传参:推荐传入 (e) => this.handleClick(id, e)

你可能感兴趣的:(React)