资讯专栏INFORMATION COLUMN

React16时代,该用什么姿势写 React ?

Reducto / 2018人阅读

摘要:的返回值将作为的参数,如果返回,则不更新,不能返回或以外的值,否则会警告。在更新之前调用,此时已更新返回值作为的第个参数一般用于获取之前的数据语法是从的返回值,默认是的使用场景一般是获取组建更新之前的滚动条位置。

React16 后的各功能点是多个版本陆陆续续迭代增加的,本篇文章的讲解是建立在 16.6.0 版本上
本篇文章主旨在介绍 React16 之后版本中新增或修改的地方,所以对于 React16 之前版本的功能,本篇文章当作您已充分了解了,不再赘述
更新概览

从 React v16.0 ~ React v16.6 的更新概览(只涉及部分常用api):

React v16.0

render支持返回数组和字符串

支持自定义 DOM 属性

减少文件体积

React v16.3

createContext

createRef

生命周期函数的更新

React v16.4

更新 getDerivedStateFromProps

React v16.6

memo

lazy

Suspense

static contextType

static getDerivedStateFromError

React v16.7(~Q1 2019)

Hooks

接下来将针对影响较大,使用频率较高的更新点逐一讲解。

纯函数的PureComponent

我们知道,对 React 组件的性能优化,shouldComponentUpdate函数是很重要的一啪,所以 React 才会在 React.Component的基础上增加了React.PureComponent,但是对于非class类的纯函数写法,却没法增加这样的便捷处理。
对于这个问题,React16.6 增加了React.memo这个高阶组件

一般使用方式:

const C = React.memo(props => {
  // xxx
})

React.memo的实现类似React.PureComponent,所以它内部是对对象进行浅比较。
React.memo允许你自定义比较方法,如下:

// 函数的返回值为 true 时则更新组件,反之则不更新
const equalMethod = (prevProps, nextProps): boolean => {
  // 定义你的比较逻辑
}
const C = React.memo(props => {
  // xxx
}, equalMethod)
新的生命周期函数是怎样的

React生命周期分为三个阶段:挂载、更新、卸载,React16后又多了一个异常,我们一一看下。

挂载 生命周期的执行顺序

constructor

static getDerivedStateFromProps

render

componentDidMount

rendercomponentDidMount较 React16 之前无变化。对于挂载过程,我们着重看下constructorcomponentWillMountstatic getDerivedStateFromProps

constructor

初始化 state
注意:应避免使用propsstate赋值,这样的话, state的初始化可以提到constructor外面处理

constructor(props) {
  super(props);
  this.state = {
    x: 1,
    // y: props.y, // 避免这样做,后面我们会讲应该怎样处理
  }
}

给方法绑定this

constructor(props) {
  super(props);
  this.handleClick = this.handleClick.bind(this);
}

但是,以上两件事放到constructor外面处理会更简单些,如下:

class C extends React.Component {
  state = {
    x: 1
  }
  handleClick = (e) => {
    // xxx
  }
}

所以,React16 以后用到constructor的场景会变少。

componentWillMount

可以看到,componentWillMount在 React16 中被“删掉”了(这样说其实是有问题的,因为 React 并未真正删除该生命周期函数,只是告诫开发者,该函数在未来版本中会被废弃掉),那么问题就出现了,原先在这个生命周期中的做的事情,现在该放到哪里去做呢?

首先问自己一个问题,原先的时候都在这个生命周期里做什么?答案是大部分时候会在这里做 AJAX 请求,然后执行setState重新渲染。

然而在componentWillMount里做 AJAX 请求实在不是一个明智之举,因为对于同构项目中,componentWillMount是会被调用的。

还有人会在这里面初始化state,关于state的初始化,请参看楼上小节。

综上所述,componentWillMount其实本来没有什么主要作用,如果你的代码规范,去掉的话,不会对现在的项目产生什么影响。

static getDerivedStateFromProps

上面我们讲到,应避免使用propsstate赋值,但是在 React16 前我们都是这么做的,现在如果不让这么操作了,那该在哪里处理这块逻辑呢? React16 给出的答案就是 static getDerivedStateFromProps
挂载组件时,该静态方法会在render前执行;更新组件时,该静态方法会在shouldComponentUpdate前执行。

class C extends React.Component {
  state = {
    y: 0
  }
  static getDerivedStateFromProps(props, state): State {
    if(props.y !== state.y) {
      return {
        y: props.y
      };
    }
  }
}

getDerivedStateFromProps的返回值将作为setState的参数,如果返回null,则不更新state,不能返回object 或 null 以外的值,否则会警告。

getDerivedStateFromProps是一个静态方法,是拿不到实例this的,所以开发者应该将该函数设计成纯函数。

这样,有没有发现componentWillReceiveProps也就没有用武之地了?是的,React16 把它也“删掉”了(这样说其实是有问题的,因为 react 并未真正删除该生命周期函数,只是告诫开发者,该函数在未来版本中会被废弃掉,建议使用更好的getSnapshotBeforeUpdategetDerivedStateFromProps

更新 生命周期函数的执行顺序

static getDerivedStateFromProps

shouldComponentUpdate

render

getSnapshotBeforeUpdate

componentDidUpdate

static getDerivedStateFromProps前面已经介绍过了,而其他的几个生命周期函数与 React16 之前基本无异,所以这里主要介绍下getSnapshotBeforeUpdate

getSnapshotBeforeUpdate

在 React 更新 DOM 之前调用,此时state已更新;
返回值作为componentDidUpdate的第3个参数;
一般用于获取render之前的 DOM 数据

语法:

class C extends React.Component {
  getSnapshotBeforeUpdate (prevProps, prevState): Snapshot {
    
  }
  componentDidUpdate(prevProps, prevState, snapshot) {
    // snapshot 是从 getSnapshotBeforeUpdate 的返回值,默认是 null
  }
}

getSnapshotBeforeUpdate 的使用场景一般是获取组建更新之前的滚动条位置。

卸载

componentWillUnmount

较之前无变化。

异常

componentDidCatch 这个函数是 React16 新增的,用于捕获组件树的异常,如果render()函数抛出错误,则会触发该函数。可以按照 try catch 来理解和使用,在可能出现错误的地方,使用封装好的包含 componentDidCatch 生命周期的组建包裹可能出错的组件。

class PotentialError extends React.Component {
  state = {
    error: false,
  }
  componentDidCatch(error, info) {
    console.error(info);
    this.setState({
      error
    });
  }
  render() {
    if (this.state.error) {
      return 

出错了,请打卡控制台查看详细错误!

; } return this.props.children; } }

如:

const Demo = () => (
  
    
{{a: 1}}
)

这样,Demo 组件即使直接使用对象作为子组件也不会报错了,因为被 PotentialError 接收了。

新生命周期的完整demo

看看穿上新生命周期这身新衣服后的样子吧

import React from "react"

export default class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    // 初始化state方式(1)
    this.state = {

    }
  }
    
  static defaultProps = {

  }

  // 初始化state方式(2)
  state = {

  }
  static getDerivedStateFromProps(props, state) {
    return state
  }
  componentDidCatch(error, info) {

  }
  render() {

  }
  componentDidMount() {

  }
  shouldComponentUpdate(nextProps, nextState) {
    
  }
  getSnapshotBeforeUpdate(prevProps, prevState) {

  }
  componentDidUpdate(prevProps, prevState, snapshot) {

  }
  componentWillUnmount() {

  }

}
Suspense Hooks time slicing

【未完待续】

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102234.html

相关文章

  • 读zent源码库之Dialog组件实现

    摘要:但是,最后一步,事件怎么绑定呢这块没有深入研究了,不过我想,应该这样去实现也是没有问题的。的具体做法是,把方法放到了一个叫做的组件上去实现这个功能,然后再把内容放进这个组件。其他的逻辑比如显示隐藏之类,全部都放到组件自身上去实现。 1、Dialog组件提供什么功能,解决什么问题? zent的Dialog组件,使用姿势是这样的(代码摘自zent官方文档:https://www.youza...

    陈江龙 评论0 收藏0
  • 深入理解js

    摘要:详解十大常用设计模式力荐深度好文深入理解大设计模式收集各种疑难杂症的问题集锦关于,工作和学习过程中遇到过许多问题,也解答过许多别人的问题。介绍了的内存管理。 延迟加载 (Lazyload) 三种实现方式 延迟加载也称为惰性加载,即在长网页中延迟加载图像。用户滚动到它们之前,视口外的图像不会加载。本文详细介绍了三种延迟加载的实现方式。 详解 Javascript十大常用设计模式 力荐~ ...

    caikeal 评论0 收藏0
  • 一段人人都应该知道的从Vue到React的过渡史

    摘要:并根据官网文档的语法顺序,写了对应的的语法,并附一个教程。和受限元素一样,使用事件可以监听值的变化。有一个初始值,但这个值用户可以改变并会反应到界面上。 写在前面 以前写Vue写惯了,心血来潮,写起了react。并根据Vue官网文档的语法顺序,写了对应的React的语法,并附一个教程demo。 教程的github地址:Close2React 项目使用框架版本主要有 react(15.4...

    chadLi 评论0 收藏0
  • 前端周刊第62期:学习学习再学习

    摘要:腾讯前端技术大会和全球技术领导力峰会都于上周闭幕,我翻看了下讲稿,有价值的参考还是不少。腾讯前端大会下载腾讯前端大会是由腾讯主办,广邀国内外的前端大牛,有著名流行框架的作者知名前端书籍的作者工程化方面的权威等。 showImg(https://segmentfault.com/img/bVQk0r?w=757&h=427); 共 2462 字,读完需 4 分钟。腾讯前端技术大会(TFC...

    tinylcy 评论0 收藏0
  • 少踩点坑,你值得知道的React事件绑定

    摘要:比如在的时候组件挂载的时候会根据指定的参数继续向下执行,则会在挂载的时候还没发生点击事件就直接执行了父组件的函数。即中转函数的效果,保证了时的函数都是并且也防止了子组件在挂载时,顺着调用父组件的函数从而避免了一系列错误。 写在前面 以前写Vue写惯了,心血来潮,写起了react。 github地址:Close2React 项目使用框架版本主要有 react(15.4.1) + reac...

    Riddler 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<