首先,把我知道从16.0开始到现在为止新特性全部列举出来:
v16.0
render 支持返回数组和字符串
createPortal
支持自定义 DOM 属性
Error Boundary
Fiber
SSR优化
减少文件体积
v16.1
react-call-return
v16.2
Fragment
v16.3
生命周期函数的更新
createContext
createRef
forwardRef
v16.4
新增Pointer Events
fix getDerivedStateFromProps bug
v16.5
React Profiler 调试
v16.6
memo
lazy
suspense
简化 contextType
增加 getDerivedStateFromError
v16.8
React hooks
v16.0
1. render支持return数组 ,字符串
React16新增加了render的返回格式,你可以return返回number,boolean,null,portal(Portals提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。),以及新支持的string和fragments(带有key属性的数组),不需要外层包含div标签,但必须有key。
render() {
// 不再需要在外边包裹一个额外的元素!
return [
// 不要忘记加key哦 :)
<li key="A"/>First item</li>,
<li key="B"/>Second item</li>,
<li key="C"/>Third item</li>,
];
}
2. Portals
Portals机制提供了一种最直接的方式可以把一个子组件渲染到父组件渲染的DOM树之外。默认情况下,React组件树和DOM树是完全对应的,因此对于一些Modal,Overlay之类的组件,通常是将它们放在顶层,但逻辑上它们可能只是属于某个子组件,不利于组件的代码组织。通过使用createPortal,我们可以将组件渲染到我们想要的任意DOM节点中,但该组件依然处在React的父组件之内。带来的一个特性就是,在子组件产生的event依然可以被React父组件捕获,但在DOM结构中,它却不是你的父组件。对于组件组织,代码切割来说,这是一个很好的属性。
3. 支持自定义DOM属性
以前的 React 版本 DOM 不识别除了 HTML 和 SVG 支持的以外属性,在 React16 版本中将会把全部的属性传递给 DOM 元素。这个新特性可以让我们摆脱可用的 React DOM 属性白名单。笔者之前写过一个方法,用于过滤非 DOM 属性 filter-react-dom-props,16 之后即可不再需要这样的方法。
4. Error Boundary
React V16之前如果页面出现错误,整个页面会崩溃掉,本次版本您提供一个稳定的api,componentDidCatch,就像 try catch一样,用于捕获渲染过程的错误信息,避免整个页面崩溃掉。在組件中加入 componentDidCatch 方法就成为 Error Boundary 組件,當「子組件」發生錯誤時就會被這個 Error Boundary 捕捉,不会让错误信息影响到其他组件。但是并不是所有错误都可以被捕捉上:
只能捕捉「子」组件错误,边界本身无法被捕捉。
只能捕捉子组件「渲染」「各生命周期方法」中的错误。
牵涉到非同步执行 (ex. setTimeout, callback ) 中的错误无法被捕捉。
无法捕捉 event handler 中发生的错误。
5. Fiber
专门写一篇文章研究。请持续关注 React 中文社区,近期推送
6. SSR优化
生成更简洁的HTML
宽松的客户端一致性校验
无需提前编译
react 16服务端渲染速度更快
支持流式渲染
1)生成更简洁的HTML
先看下面的HTML,react 15与react 16的服务端分别会生成什么。
renderToString(
<div>
This is some <span>server-generated</span> <span>HTML.</span>
</div> );
react15:
有data-reactid, text noded ,react-text各种属性。
<div data-reactroot="" data-reactid="1"
data-react-checksum="122239856">
<!-- react-text: 2 -->This is some <!-- /react-text -->
<span data-reactid="3">server-generated</span>
<!-- react-text: 4--> <!-- /react-text -->
<span data-reactid="5">HTML.</span>
</div>
react 16:
<div data-reactroot="">
This is some <span>server-generated</span>
<span>HTML.</span>
</div>
可以看到,react 16去掉了很多属性,它的好处很明显:增加易读性,同时很大程度上减少html的文件大小。
2) 宽松的客户端一致性校验
react 15:会将SSR的结果与客户端生成的做一个个字节的对比校验 ,一点不匹配发出waring同时就替换整个SSR生成的树。
react 16:对比校验会更宽松一些,比如,react 16允许属性顺序不一致,而且遇到不匹配的标签,还会做子树的修改,不是整个替换。
注意点:react16不会自动fix SSR 属性跟client html属性的不同,但是仍然会报waring,所以我们需要自己手动去修改。
3) 无需提前编译
react 15:如果你直接使用SSR,会有很多需要检查procee.env的地方,但是读取在node中读取process.env是很消耗时间的。所以在react 15的时候,需要提前编译,这样就可以移除 process.env的引用。
react 16:只有一次检查process.env的地方,所以就不需要提前编译了,可以开箱即用。
4) react 16服务端渲染速度更快
为什么呢?因为react 15下,server client都需要生成vDOM,但是其实在服务端, 当我们使用renderToString的时候,生成的vDom就会被立即抛弃掉, 所以在server端生成vDom是没有意义的。
5) 支持流式渲染 (renderyToNodeStream)
使用流式渲染会提升首个字节到(TTFB)的速度。但是什么是流式渲染呢?
可以理解为内容以一种流的形式传给前端。所以在下一部分的内容被生成之前,开头的内容就已经被发到浏览器端了。这样浏览器就可以更早的编译渲染文件内容。
7. 减小了32%bundle的体积
React 库大小从 20.7kb(压缩后 6.9kb)降低到 5.3kb(压缩后 2.2kb)
ReactDOM 库大小从 141kb(压缩后 42.9kb)降低到 103.7kb(压缩后 32.6kb)