很多等待已久的特性:
包括: fragments, error boundaries, portals, 支持 custom DOM attributes, 改進 server-side rendering, reduced file size
render
方法可以返回新類型: fragments
and strings
現(xiàn)在組件的 render
方法里可以直接返回數(shù)組。像在其它地方使用數(shù)組一樣,這里每個數(shù)組元素也要加上key
屬性。
render() {
return [
// Don't forget the keys :)
<li key="A">First item</li>,
<li key="B">Second item</li>,
<li key="C">Third item</li>,
];
}
注:
fragments
實際指的就是array
, 在這之前如果你想簡單返回一個array
, 不好意思,不行!
上面的代碼會爆這個錯誤 Adjacent XJS elements must be wrapped in an enclosing tag.
現(xiàn)在返回array
時還是要加key屬性吱殉,接下來React Team會讓JSX
支持一種不需要key
的fragment
語法。
另外直接返回string
也是支持的, 完整的 render
返回類型可參考.
render() {
return 'Look ma, no spans!';
}
更好的錯誤處理
在之前鹦牛,渲染時發(fā)生的runtime errors
會令React處于異常狀態(tài), 同時產(chǎn)生一些莫名其妙的錯誤消息,只有通過刷新整個頁面才能恢復勇吊。React 16采取了一種更靈活的策略來處理這個問題曼追。默認情況下,如果在組件的render
或lifecycle
方法中拋出了錯誤汉规,整個組件樹會從根節(jié)點被unmount下來礼殊。這樣做的好處是,已經(jīng)被破壞的數(shù)據(jù)不會被顯示出來针史,但帶來的用戶體驗并不理想晶伦。
除了把整個app在每次出錯時都unmount
下來,你還可以使用error boundaries. 每一個boundaries都是特殊的React組件啄枕,它可以捕獲它子樹的里發(fā)生的錯誤婚陪,并在它控制區(qū)域中顯示一個fallback UI,可以把它想像成傳統(tǒng)的try-catch
語句频祝,但僅用于React組件泌参。
如果要了解更多細節(jié),請看previous post on error handling in React 16.
Portals
Portals
提供了一種最直接的方式去把一個子組件渲染到父組件所控制的DOM樹之外的節(jié)點常空。
render() {
// React does *not* create a new div. It renders the children into `domNode`.
// `domNode` is any valid DOM node, regardless of its location in the DOM.
return ReactDOM.createPortal(
this.props.children,
domNode,
);
}
注:最直接的應用就是用來實現(xiàn)像modal, tooltip之類的組件及舍,這些組件的DOM元素通常會直接被放到頂層,但邏輯上它們又可能只是屬于某個子組件的窟绷。
還有一點要特別留意的是锯玛,在用Portal的時候,你只是把DOM渲染到父組件之外兼蜈,但子組件(就是調用Portal那個)還是在React的父組件之內攘残,就是React的組件樹結構不變,不受Portal的調用(或者說DOM結構)影響为狸。
帶來的一個特性就是歼郭,你在子組件產(chǎn)生的event會被你的React父組件所捕獲,即使在DOM中辐棒,它不是你的父組件病曾。對組件的組織牍蜂,代碼的切割來所,這應該是個好特性泰涂,但如果你同時操作 DOM的話鲫竞,可能會需要一些特殊處理
更好的服務器端渲染
React 16 里把服務器渲染(SSR)徹底重寫了一遍。新的實現(xiàn)非潮泼桑快从绘,并且支持 streaming, 現(xiàn)在你可以更快地把渲染的字節(jié)發(fā)送到客戶端。
多虧了在 新的打包策略 中去掉了process.env
檢查(信不信由你, 在node.js
里讀取process.env
真的很慢)是牢,現(xiàn)在你不再需要在服務器端重新打包一次React也可以有不錯的服務端渲染性能僵井。
核心小組的Sasha Aickin寫了一篇很棒的文章來闡述React 16里的改進
. 根據(jù) Sasha's 的模擬benchmarks
, React 16里的服務端渲染性能 3倍于React 15.
"When comparing against React 15 with process.env compiled out, there’s about a 2.4x improvement in Node 4, about a 3x performance improvement in Node 6, and a full 3.8x improvement in the new Node 8.4 release. And if you compare against React 15 without compilation, React 16 has a full order of magnitude gain in SSR in the latest version of Node!" (As Sasha points out, please be aware that these numbers are based on synthetic benchmarks and may not reflect real-world performance.)
另外,React 16在hydrating
(注:指在客戶端基于服務器返回的HTML再次重新渲染)方面也表現(xiàn)的更好驳棱。React 16
不再要求客戶端的初始渲染完全和服務器返回的渲染結果一致批什,而是盡量重用已經(jīng)存在的DOM元素。不再會有checkusm!
一般來說社搅,在服務器和客戶端渲染不同的內容是不建議的渊季,但這樣做在某些情況下也是有用的(比如,生成timestamp).
documentation for ReactDOMServer
有更多細節(jié)可供參考
支持自定義DOM屬性
React不再忽略無法識別的HTML和SVG屬性罚渐,現(xiàn)在它會把這些屬性直接傳遞給DOM. 這個改動讓React可以去掉屬性白名單却汉,從而減小了文件大小
縮減文件大小
盡管添加了這些新特性, React 16 實際上比 15.6.1還要苗條
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).
總體上就是比上個版本減小了 32% (30% post-gzip).
文件尺寸的減小一部分要歸功于打包方法的改變。
React now uses Rollup to create flat bundles for each of its different target formats, resulting in both size and runtime performance wins. The flat bundle format also means that React's impact on bundle size is roughly consistent regardless of how your ship your app, whether it's with Webpack, Browserify, the pre-built UMD bundles, or any other system.
MIT licensed
如果你沒有讀過荷并,點我, React 16 現(xiàn)在使用MIT license. 為了那些不能立刻升級React的同志們合砂,我們也用MIT發(fā)布了React 15.6.2。
新的核心架構
React 16 是第一個使用新架構Fiber的版本源织。你可以在這里了解所有詳情
(劇透一下: 我們重寫了React!)
大部分的新特性翩伪,像error boundaries, fragments,都可以歸功于Fiber谈息。接下來的發(fā)布的版本缘屹,你們可以期待更多的新特性,因為我們要釋放React的所有潛能侠仇。
最令人興奮的大概就是異步渲染轻姿。
通過異步渲染, 程序可以更流暢地運行,因為React可以避免阻塞主線程逻炊。