内容简介:React16 后的各功能点是多个版本陆陆续续迭代增加的,本篇文章的讲解是建立在本篇文章主旨在介绍 React16 之后版本中新增或修改的地方,所以对于 React16 之前版本的功能,本篇文章当作您已充分了解了,不再赘述从 React v16.0 ~ React v16.6 的更新概览(只涉及部分常用api):
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
render
和 componentDidMount
较 React16 之前无变化。对于挂载过程,我们着重看下 constructor
、 componentWillMount
和 static getDerivedStateFromProps
。
constructor
-
初始化 state
注意:应避免使用props给state赋值,这样的话, 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
上面我们讲到,应避免使用props给state赋值,但是在 React16 前我们都是这么做的,现在如果不让这么操作了,那该在哪里处理这块逻辑呢? React16 给出的答案就是 static getDerivedStateFromProps
,挂载组件时,该静态方法会在 render
前执行。
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 并未真正删除该生命周期函数,只是告诫开发者,该函数在未来版本中会被废弃掉,建议使用更好的 getSnapshotBeforeUpdate
或 getDerivedStateFromProps
)
更新
生命周期函数的执行顺序
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 <h1>出错了,请打卡控制台查看详细错误!</h1>; } return this.props.children; } }
如:
const Demo = () => ( <PotentialError> <div>{{a: 1}}</div> </PotentialError> )
这样, 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
【未完待续】
以上所述就是小编给大家介绍的《React16时代,该用什么姿势写 React ?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 强大的姿势感知模型用于姿势不变的人脸识别
- 从姿势到图像——基于人体姿势引导的时尚图像生成算法
- 行人重识别告别辅助姿势信息,港中文、商汤等提出姿势无关的特征提取GAN
- 穿越边界的姿势
- 日志打印的正确姿势!
- 修复缺陷的正确姿势
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Delivering Happiness
Tony Hsieh / Grand Central Publishing / 2010-6-7 / USD 27.00
http://www.deliveringhappinessbook.com/ The visionary CEO of Zappos explains how an emphasis on corporate culture can lead to unprecedented success. Pay new employees $2000 to quit. Make custome......一起来看看 《Delivering Happiness》 这本书的介绍吧!
Base64 编码/解码
Base64 编码/解码
XML、JSON 在线转换
在线XML、JSON转换工具