React16新特性
React的16版本采用了MIT开源许可证,新增了一些特性。
- Error Boundary
- render方法新增返回类型
- Portals
- 支持自定义DOM属性
- setState传入null时不会再触发更新
- 更好的服务器端渲染
- 新的打包策略
- ...
1. 使用Error Boundary处理错误组件
之前,一旦某个组件发生错误,整个组件树将会从根节点被unmount下来。React 16修复了这一点,引入了Error Boundary的概念,中文译为“错误边界”,当某个组件发生错误时,我们可以通过Error Boundary捕获到错误并对错误做优雅处理,如使用Error Boundary提供的内容替代错误组件。Error Boundary可以看作是一种特殊的React组件,新增了componentDidCatch这个生命周期函数,它可以捕获自身及子树上的错误并对错误做优雅处理,包括上报错误日志、展示出错提示,而不是卸载整个组件树。(注:它并不能捕获runtime所有的错误,比如组件回调事件里的错误,可以把它想象成传统的try-catch
语句)
//最佳实践:将ErrorBoundary抽象为一个公用的组件类
import React, { Component } from 'react'
export default class ErrorBoundary extends Component {
constructor(props) {
super(props)
this.state = { hasError: false }
}
componentDidCatch(err, info) {
this.setState({ hasError: true })
//sendErrorReport(err,info)
}
render(){
if(this.state.hasError){
return <div>Something went wrong!</div>
}
return this.props.children
}
}
我们可以在容易出错的组件外使用ErrorBoundary将它包裹起来,如下
//使用方式
render(){
return (
<div>
<ErrorBoundary>
<Profile user={this.state.user} />
</ErrorBoundary>
<button onClick={this.onClick}>Update</button>
</div>
)
}
如果Profile组件发生错误,将会使用ErrorBoundary提供的<div>Something went wrong</div>
代替它,而不会引起整个组件树的卸载。
2. render方法新增返回类型
在React 16中,render方法支持直接返回string,number,boolean,null,portal,以及fragments(带有key属性的数组),这可以在一定程度上减少页面的DOM层级。
//string
render(){
return 'hello'
}
//number
render(){
return 88888
}
//boolean
render(){
return istrue?true:false
}
//null
render(){
return null
}
//fragments,未加key标识符,控制台会出现warning
render(){
return [
<div>hello</div>,
<span>world</span>,
<p>oh</p>
]
}
以上各种类型现在均可以直接在render中返回,不需要再在外层包裹一层容器元素,不过在返回的数组类型中,需要在每个元素上加一个唯一且不变的key值,否则控制台会报一个warning。
3.使用createPortal将组件渲染到当前组件树之外
Portals机制提供了一种最直接的方式可以把一个子组件渲染到父组件渲染的DOM树之外。默认情况下,React组件树和DOM树是完全对应的,因此对于一些Modal,Overlay之类的组件,通常是将它们放在顶层,但逻辑上它们可能只是属于某个子组件,不利于组件的代码组织。通过使用createPortal,我们可以将组件渲染到我们想要的任意DOM节点中,但该组件依然处在React的父组件之内。带来的一个特性就是,在子组件产生的event依然可以被React父组件捕获,但在DOM结构中,它却不是你的父组件。对于组件组织,代码切割来说,这是一个很好的属性。
//实现一个简易蒙层效果,抽象出一个通用的Overlay组件
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
export default class Overlay extends Component {
constructor(props) {
super(props);
this.container = document.createElement('div');
document.body.appendChild(this.container);
}
componentWillUnmount() {
document.body.removeChild(this.container);
}
render() {
return ReactDOM.createPortal(
<div className='overlay'>
<span className='overlay-close' onClick={this.props.onClose}>×</span>
{this.props.children}
</div>,
this.container
)
}
}
//该组件对应的样式如下
.overlay{
box-sizing:border-box;
position: fixed;
top:50%;
left:50%;
width:260px;
height:200px;
margin-left:-130px;
margin-top:-100px;
padding:10px;
background-color: #fff;
outline: rgba(0,0,0,.5) solid 9999px;
}
.overlay-close{
position: absolute;
top:10px;
right:10px;
color:red;
cursor: pointer;
}
使用方式如下:
class App extends Component {
constructor(props) {
super(props);
this.state = {
overlayActive: false
}
this.closeOverlay = this.closeOverlay.bind(this);
this.showOverlay = this.showOverlay.bind(this);
}
closeOverlay() {
this.setState({ overlayActive: false })
}
showOverlay() {
this.setState({ overlayActive: true })
}
render() {
return (
<div className="App">
<div>hello world!</div>
{this.state.overlayActive &&
<Overlay onClose={this.closeOverlay}>overlay content</Overlay>}
<button onClick={this.showOverlay}>show</button>
</div>
);
}
}
效果如图:

4.支持自定义DOM属性
在之前的版本中,React会忽略无法识别的HTML和SVG属性,自定义属性只能通过data-*
形式添加,现在它会把这些属性直接传递给DOM(这个改动让React可以去掉属性白名单,从而减少了文件大小),不过有些写法仍然是无效的。如DOM传递的自定义属性是函数类型或event handler时,依然会被React忽略。
//错误写法
render(){
return(
<div a={()=>{}} onclick={this.showOverlay}></div>
)
)
//Warning: Invalid event handler property `onclick`. Did you mean `onClick`?
//Warning: Invalid value for prop `a` on <div> tag. Either remove it from the element, or pass a string or number value to keep it in the DOM.
现在class和tabindex等属性可以被传递给DOM,但依然会报一个Warning,建议使用标准的驼峰式className,tabIndex等。
5.setState传入null时不会再触发更新
比如在一个选择城市的函数中,当点击某个城市时,newValue的值可能发生改变,也可能是点击了原来的城市,值没有变化,返回null则可以直接避免触发更新,不会引起重复渲染,不需要在shouldComponentUpdate函数里面去判断。
selectCity(e){
const newValue = e.target.value;
this.setState((state)=>{
if(state.city===newValue){
return null;
}
return {city:newValue}
})
)
注意:现在setState回调(第二个参数)会在componentDidMount
/componentDidUpdate
后立即触发,而不是等到所有组件渲染完成之后。
6.更好的服务器端渲染
React 16的SSR被完全重写,新的实现非常快,接近3倍性能于React 15,现在提供一种流模式streaming,可以更快地把渲染的字节发送到客户端。另外,React 16在hydrating
(注:指在客户端基于服务器返回的HTML再次重新渲染)方面也表现的更好,React 16不再要求客户端的初始渲染完全和服务器返回的渲染结果一致,而是尽量重用已经存在的DOM元素。不会再有checksum(标记验证)!并对不一致发出警告。一般来说,在服务器和客户端渲染不同的内容是不建议的,但这样做在某些情况下也是有用的(比如,生成timestamp)。
7.新的打包策略
新的打包策略中去掉了process.env
检查。
React 16的体积比上个版本减小了32%(30% post-gzip),文件尺寸的减小一部分要归功于打包方法的改变。
react is 5.3 kb (2.2 kb gzipped), down from 20.7 kb (6.9 kb gzipped).
react-dom is 103.7 kb (32.6 kb gzipped), down from 141 kb (42.9 kb gzipped).
react + react-dom is 109 kb (34.8 kb gzipped), down from 161.7 kb (49.8 kb gzipped).
写在最后,React 16采用了新的核心架构React Fiber。官方解释是“React Fiber是对核心算法的一次重新实现”。
React16新特性的更多相关文章
- React16 新特性
一.使用Error Boundary处理错误组件 React16之前:组件在运行期出错,会阻塞整个应用的渲染. React16之后:引入新的错误处理机制——Error Bounda ...
- 🍓 react16.2新特性 🍓
react16.2新特性:组件中可以一次性return 多个子元素(子组件)了,也就是说,想return多个子元素,不用在外面包一个父盒子了. 方法一:把要return的元素放在一个空的jsx里面 方 ...
- React16版本的新特性
React16版本更新的新特性 2018年05月03日 21:27:56 阅读数:188 1.render方法的返回值类型:New render return types 之前的方式: class A ...
- [译文]React v16(新特性)
[译文]React v16(新特性) 查看原文内容 我们很高兴的宣布React v16.0发布了! 这个版本有很多长期被使用者期待的功能,包括: fragments (返回片段类型) error bo ...
- react 16.8版本新特性以及对react开发的影响
Facebook团队对社区上的MVC框架都不太满意的情况下,开发了一套开源的前端框架react,于2013年发布第一个版本. react最开始倡导函数式编程,使用function以及内部方法React ...
- SQL Server 2014 新特性——内存数据库
SQL Server 2014 新特性——内存数据库 目录 SQL Server 2014 新特性——内存数据库 简介: 设计目的和原因: 专业名词 In-Memory OLTP不同之处 内存优化表 ...
- ElasticSearch 5学习(10)——结构化查询(包括新特性)
之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...
- [干货来袭]C#6.0新特性
微软昨天发布了新的VS 2015 ..随之而来的还有很多很多东西... .NET新版本 ASP.NET新版本...等等..太多..实在没消化.. 分享一下也是昨天发布的新的C#6.0的部分新特性吧.. ...
- CSS3新特性应用之结构与布局
一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...
随机推荐
- ArcEngine中加载ArcGIS Server地图服务
代码如下: private void addMapServerLayer(object sender, EventArgs e) { IActiveView pActiveV ...
- butter
题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油.当然,他将付出额外的费 ...
- 把myeclipse的自动验证和自动构建都关掉
关闭自动构建: project - -build automatically 的勾去掉,如下图: 关闭自动验证:window - preferences-- myeclipse -- valida ...
- Gazebo仿真
1.建议在本地Ubuntu 16.04下运行仿真程序.目前Gazebo模拟器的兼容性是一大问题,在虚拟机或配置较低的电脑上可能无法运行.如果你的显卡是N卡,建议安装Ubuntu下的显卡驱动. 2.运行 ...
- 201904:Action recognition based on 2D skeletons extracted from RGB videos
论文标题:Action recognition based on 2D skeletons extracted from RGB videos 发表时间:02 April 2019 解决问题/主要思想 ...
- Objective-C GCD深入理解
GCD(Grand Central Dispatch),主要用于多线程编程.它屏蔽了繁琐的线程实现及管理细节,将其交由系统处理.开发者只需要定义任务block(在底层被封装成dispatch_cont ...
- ASP 基础一 基本语法
一 声明变量 二 给变量赋值 三 循环 四 case <html> <head title="test hello world"> </head> ...
- CF809E Surprise me! 莫比乌斯反演、虚树
传送门 简化题意:给出一棵\(n\)个点的树,编号为\(1\)到\(n\),第\(i\)个点的点权为\(a_i\),保证序列\(a_i\)是一个\(1\)到\(n\)的排列,求 \[ \frac{1} ...
- Maven私有仓库: 发布release版本报错:Return code is: 400, ReasonPhrase: Repository does not allow upd ating assets: maven-releases.
今天在将一个maven组件由SNAPSHORT升级为正式版本1.0.0,然后执行发布: mvn clean deploy -pl ielong-common -am -DskipTests, 报错:R ...
- IDC Digital Transition Annual Festival(2018.10.19)
时间:2018.10.19地点:北京万达文化酒店