原文:https://deploy-preview-10824--reactjs.netlify.com/blog/2017/09/26/react-v16.0.html
譯者:miaoyu
我們很高興的宣布React v16.0發(fā)布了,這次版本的新增了一些呼聲很高的特性,包括支持render返回?cái)?shù)組和字符串、錯(cuò)誤處理、portals、自定義DOM屬性、優(yōu)化服務(wù)器端渲染以及減少文件大小。
支持render返回?cái)?shù)組和字符串
你現(xiàn)在可以通過(guò)render
方法返回一個(gè)包含元素的數(shù)組:
render() {
// 不再需要在外邊包裹一個(gè)額外的元素!
return [
// 不要忘記加key哦 :)
<li key="A"/>First item</li>,
<li key="B"/>Second item</li>,
<li key="C"/>Third item</li>,
];
}
同時(shí)也支持返回字符串。
更好的錯(cuò)誤處理
在此之前,React在渲染時(shí)運(yùn)行錯(cuò)誤會(huì)導(dǎo)致渲染中斷,接著拋出一個(gè)令人匪夷所思的錯(cuò)誤以及要求刷新頁(yè)面來(lái)恢復(fù)。為了解決這個(gè)問(wèn)題,React16 使用了更有彈性的錯(cuò)誤處理策略。如果在組件的render
方法或者生命周期方法中拋出錯(cuò)誤,整個(gè)組件會(huì)被卸載。這樣可以阻止顯示錯(cuò)誤的頁(yè)面。然而這可能不是理想的用戶體驗(yàn)。
每當(dāng)錯(cuò)誤發(fā)生時(shí),你可以使用錯(cuò)誤邊界而不是卸載整個(gè)應(yīng)用。錯(cuò)誤邊界是一個(gè)特殊的組件,捕捉組件樹(shù)的錯(cuò)誤然后顯示降級(jí)的UI來(lái)提升體驗(yàn)。其實(shí)錯(cuò)誤邊界就像try-catch語(yǔ)句,只不過(guò)是用于React。
想獲得更詳細(xì)的信息, 查看我們之前的文章.
Portals
Portals提供一個(gè)方法來(lái)渲染DOM層級(jí)之外的DOM節(jié)點(diǎn)。
render() {
// React不需要?jiǎng)?chuàng)建一個(gè)新的div。將被渲染到`divNode`中。
// `divNode` 是一個(gè)在DOM中任何地方都有效的節(jié)點(diǎn)。
return React.createPortal(
this.props.children,
divNode,
);
}
更好的服務(wù)器端渲染
不再要求初始渲染和服務(wù)器的結(jié)果完全匹配,取而代之的是嘗試重用更多已存在的節(jié)點(diǎn)。減少校驗(yàn)!
服務(wù)器端渲染的特性被完全重寫(xiě)以支持?jǐn)?shù)據(jù)流。React核心團(tuán)隊(duì)成員Sasha Aicken(主要負(fù)責(zé)這個(gè)特性),他寫(xiě)了一篇很牛逼的文章來(lái)描述React16服務(wù)器端渲染的提升:“對(duì)流的渲染可以節(jié)省時(shí)間,在document后面部分生成之前就可以把document前面部分發(fā)送給瀏覽器。所有主流的瀏覽器,都會(huì)在當(dāng)服務(wù)器傳輸流時(shí),開(kāi)始解析和渲染document。”
支持自定義DOM屬性
React將不再忽略未被識(shí)別的HTML和SVG屬性,React會(huì)將它們傳遞給DOM。這樣還帶來(lái)一個(gè)好處就是允許我們把它們從React屬性的白名單剔除出去,從而減小了文件大小。
縮小React的體積
盡管內(nèi)容有所增加,但React 16的實(shí)際大小比起15.6.1小得多!
react
文件大小從20.7kb(壓縮文件6.9kb)縮小到5.3kb(壓縮文件2.2kb)。react-dom
文件大小從141kb(壓縮文件42.9kb)縮小到103.7kb(壓縮文件32.6kb)。react
+react-dom
文件大小從161.7kb(壓縮文件49.8kb)縮小到109kb(壓縮文件34.8kb)。
與前一個(gè)版本相比,大小減少了32%(壓縮后大小減少了30%)。
體積的縮小主要是因?yàn)榇虬绞降母淖儭eact使用Rollup 來(lái)為不同的目標(biāo)格式創(chuàng)建bundles,帶來(lái)的結(jié)果不僅僅是體積減小也使得運(yùn)行時(shí)性能得到提升。
全新架構(gòu)
React16是在新架構(gòu)之上第一個(gè)版本,代號(hào)“Fiber”。
這次發(fā)布的大部分特性,比如錯(cuò)誤邊界和fragments,都是重寫(xiě)核心代碼實(shí)現(xiàn)的。在接下來(lái)的幾個(gè)版本中,你可以期待更多的特性,因?yàn)镽eact的無(wú)限潛能已經(jīng)被激發(fā)出來(lái)了。
我們正在開(kāi)發(fā)異步渲染———一種瀏覽器定期協(xié)同渲染策略,異步渲染會(huì)使應(yīng)用響應(yīng)更穩(wěn)定,因?yàn)镽eact不會(huì)阻塞主線程。
我們認(rèn)為異步渲染是一個(gè)很好的解決方案,它也代表了React未來(lái)的方向。這個(gè)特性會(huì)盡可能平順的遷移到v16.0,目前我們還沒(méi)有啟用任何異步特性,但是我們很高興會(huì)在接下來(lái)幾個(gè)月推出這一解決方案,請(qǐng)持續(xù)關(guān)注!
升級(jí)
盡管React16包含了很重大內(nèi)部改變,但在升級(jí)方面,和之前發(fā)布React版本一樣。在一般情況下,如果你的應(yīng)用運(yùn)行在15.6上沒(méi)有任何警告提示,那就可以運(yùn)行在16上。
注意
如果你在服務(wù)器端渲染HTML,請(qǐng)使用ReactDOM.hydrate替換ReactDOM.render。如果你只是在客戶端渲染,那么請(qǐng)繼續(xù)使用ReactDOM.render。
重大改變
unstable_handleError
方法改名為componentDidCatch
,你可以用codemod
自動(dòng)遷移到新的API。如果在生命周期中調(diào)用
ReactDOM.render
和ReactDOM.unstable_renderIntoContainer
這兩個(gè)方法會(huì)返回null,如果真有這種需求,可以使用portals或者refs。-
setState
:調(diào)用setState傳入null將不會(huì)觸發(fā)更新。
直接在render方法中調(diào)用
setState
會(huì)導(dǎo)致更新。不管怎樣,你也不應(yīng)該在render方法中調(diào)用setState
。setState
的回調(diào)函數(shù)(第二個(gè)參數(shù)),在componentDidMount
或componentDidUpdate
方法執(zhí)行后立即調(diào)用。
當(dāng)用
<B />
替換<A />
,B組件的componentWillMount
會(huì)在A組件的componentWillUnmount
之前執(zhí)行。在此之前,改變組件的ref,總會(huì)在調(diào)用改組件render方法之前分離ref,現(xiàn)在是讓它在 DOM 變更后再做改變。
通過(guò)非React方式修改組件后重新渲染是很不安全的,雖然在之前的版本中可行,但是現(xiàn)在我們會(huì)拋出警告,除非你使用
ReactDOM.unmountComponentAtNode
來(lái)清除你的組件樹(shù)。查看示例componentDidUpdate
生命周期不會(huì)再返回prevContext
參數(shù)。(查看 #8631)淺渲染不在調(diào)用
componentDidUpdate()
,因?yàn)镈OM的refs是不可用的。這也使得它和componentDidMount()
保持一致(componentDidMount()
在之前的版本也是不會(huì)調(diào)用的)。淺渲染不再執(zhí)行
unstable_batchedUpdates()
打包
不再有
react/lib/*
和react-dom/lib/*
兩個(gè)路徑。即使是在CommonJS環(huán)境中,React和ReactDOM預(yù)編譯成一個(gè)單獨(dú)的文件。如果你之前依賴React內(nèi)部文件,并且不再工作了,那么請(qǐng)告訴我們你的具體情況,我們會(huì)嘗試為你制定遷移策略。不再有
react-with-addons.js
編譯版本,所有兼容的插件都會(huì)在npm上單獨(dú)發(fā)布,如果你需要的話有單個(gè)文件應(yīng)用于瀏覽器的版本。React.createClass
現(xiàn)在等同于create-react-class
,React.PropTypes
等同于prop-types
,React.DOM
等同于react-dom-factories
,react-addons-test-utils
等同于react-dom/test-utils
, 以及淺渲染等同于react-test-renderer/shallow
,請(qǐng)參閱 15.5.0 和 15.6.0 的文章 來(lái)遷移代碼。-
應(yīng)用于瀏覽器的單個(gè)文件的文件名和路徑被修改了,目的是為了區(qū)分開(kāi)發(fā)模式和生產(chǎn)模式,比如:
react/dist/react.js
→react/umd/react.development.js
react/dist/react.min.js
→react/umd/react.production.min.js
react-dom/dist/react-dom.js
→react-dom/umd/react-dom.development.js
react-dom/dist/react-dom.min
.js →react-dom/umd/react-dom.production.min.js