setState 一定是异步的吗?
setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是“同步”的。
你真的理解setState吗?
Fiber
Fiber 本质上是一个虚拟的堆栈帧,新的调度器会按照优先级自由调度这些帧,从而将之前的同步渲染改成了异步渲染,在不影响体验的情况下去分段计算更新。
对于如何区别优先级,React 有自己的一套逻辑。对于动画这种实时性很高的东西,也就是 16 ms 必须渲染一次保证不卡顿的情况下,React 会每 16 ms(以内) 暂停一下更新,返回来继续渲染动画。
对于异步渲染,现在渲染有两个阶段:reconciliation 和 commit 。前者过程是可以打断的,后者不能暂停,会一直更新界面直到完成。
Reconciliation 阶段
componentWillMount
componentWillReceiveProps(使用 getDerivedStateFromProps 代替)
shouldComponentUpdate
componentWillUpdate
Commit 阶段
componentDidMount
componentDidUpdate
componentWillUnmount
react
生命周期函数
|
|
import React from ‘react’;
import {createPortal} from ‘react-dom’;
class Dialog extends React.Component {
constructor() {
super(…arguments);
const doc = window.document;
this.node = doc.createElement('div');
doc.body.appendChild(this.node);
}
render() {
return createPortal(
{this.props.children}
this.node //传送门的另一端DOM node
);
}
componentWillUnmount() {
window.document.body.removeChild(this.node);
}
}
```
React-DOM Portal
React16新特性
Error Boundary(错误边界)
之前,一旦某个组件发生错误,整个组件树将会从根节点被unmount下来。
Error Boundary可以看作是一种特殊的React组件,新增了componentDidCatch这个生命周期函数,它可以捕获自身及子树上的错误并对错误做优雅处理,包括上报错误日志、展示出错提示,而不是卸载整个组件树。(注:它并不能捕获runtime所有的错误,比如组件回调事件里的错误,可以把它想象成传统的try-catch语句)
PS:最佳实践封装通用错误组件,用起包裹可能出错的组件,来捕获子组件可能发生的错误。
render方法新增返回类型
render方法支持直接返回string,number,boolean,null,portal,以及fragments(带有key属性的数组),这可以在一定程度上减少页面的DOM层级。
支持自定义DOM属性
现在React可以将属性直接传递给DOM,不过有些写法任然无效。
setState传入null时不会再触发更新
比如在一个选择城市的函数中,当点击某个城市时,newValue的值可能发生改变,也可能是点击了原来的城市,值没有变化,返回null则可以直接避免触发更新,不会引起重复渲染,不需要在shouldComponentUpdate函数里面去判断。
十分钟快速了解React16新特性
React编码优化
- 使用 key 属性为列表项组件做身份标记
- shouldComponentUpdate 决定组件是否render
- PureComponent 来定义组件
- Stateless components 函数式组件
- 慎用bind,它会返回一个新的函数