摘要:就像人們對(duì)更新移動(dòng)應(yīng)用程序和操作系統(tǒng)感到興奮一樣,開發(fā)人員也應(yīng)該對(duì)更新框架感到興奮。錯(cuò)誤邊界是一種組件。注意將作為值傳遞進(jìn)去并不會(huì)導(dǎo)致使用。如果兩者不同,則返回一個(gè)用于更新狀態(tài)的對(duì)象,否則就返回,表示不需要更新狀態(tài)。
就像人們對(duì)更新移動(dòng)應(yīng)用程序和操作系統(tǒng)感到興奮一樣,開發(fā)人員也應(yīng)該對(duì)更新框架感到興奮。不同框架的新版本具有新特性和開箱即用的技巧。
下面是將現(xiàn)有應(yīng)用程序從 React 15 遷移到 React 16 時(shí)應(yīng)該考慮的一些好特性。
想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你!
錯(cuò)誤處理React 16 引入了錯(cuò)誤邊界的新概念。
現(xiàn)在在React 16中,大家就能使用錯(cuò)誤邊界功能,而不用一發(fā)生錯(cuò)誤就解除整個(gè)程序掛載了。把錯(cuò)誤邊界看成是一種類似于編程中try-catch語句的機(jī)制,只不過是由 React 組件來實(shí)現(xiàn)的。
錯(cuò)誤邊界是一種React組件。它及其子組件形成一個(gè)樹型結(jié)構(gòu),能捕獲JavaScript中所有位置的錯(cuò)誤,記錄下錯(cuò)誤,并且還能顯示一個(gè)后備界面,避免讓用戶直接看到組件樹的崩潰信息。
這里涉及到一種新的生命周期函數(shù)叫componentDidCatch(error, info)。無論什么樣的類組件,只要定義了這個(gè)函數(shù),就成為了一個(gè)錯(cuò)誤邊界。
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } componentDidCatch(error, info) { // Display fallback UI this.setState({ hasError: true }); // 你還可以將錯(cuò)誤記錄到錯(cuò)誤報(bào)告服務(wù)中 logErrorToMyService(error, info); } render() { if (this.state.hasError) { // 可以渲染任何自定義回退界面 returnSomething went wrong.
; } return this.props.children; } }
也可以將其用作常規(guī)組件使用:
componentDidCatch() 方法的工作原理類似于JavaScript catch{}塊,但它適用于組件。只有類組件可以是錯(cuò)誤邊界。實(shí)際上,在大多數(shù)情況下,你都希望聲明一次錯(cuò)誤邊界組件,然后在整個(gè)應(yīng)用程序中使用它。
請(qǐng)注意,錯(cuò)誤邊界只會(huì)捕獲位于它們之下的組件中的錯(cuò)誤。錯(cuò)誤邊界無法捕獲到自身的錯(cuò)誤。如果錯(cuò)誤邊界渲染錯(cuò)誤消息失敗,錯(cuò)誤將被傳播到上方最接近的錯(cuò)誤邊界。這也類似于 JavaScript 中的 catch{}塊。
有了錯(cuò)誤邊界,即使某個(gè)組件的結(jié)果有錯(cuò)誤,整個(gè)React程序掛載也不會(huì)被解除。只有出錯(cuò)的那個(gè)組件會(huì)顯示一個(gè)后備界面,而整個(gè)程序仍然完全正常運(yùn)行。
點(diǎn)擊查看在線事例
關(guān)于錯(cuò)誤邊界更多的內(nèi)容可查看官網(wǎng)。
新的 render 返回類型:片段和字符串現(xiàn)在,在渲染時(shí)可以擺脫將組件包裝在 div 中。
你現(xiàn)在可以從組件的 render 方法返回元素?cái)?shù)組。與其他數(shù)組一樣,你需要為每個(gè)元素添加一個(gè)鍵以避免發(fā)出鍵警告:
render() { // No need to wrap list items in an extra element! return [ // Don"t forget the keys :)
從React 16.2.0開始,它支持JSX的一個(gè)特殊片段語法,該語法不需要鍵。
render() { return ( <>> ); }
支持返回字符串:
render() { return "Look ma, no spans!"; }Portal
Portal 提供了一種將子節(jié)點(diǎn)渲染到父節(jié)點(diǎn)之外的 dom 節(jié)點(diǎn)。
ReactDOM.createPortal(child, container)
第一個(gè)參數(shù) (child)是任何可渲染的 React子元素,例如元素,字符串或片段。 第二個(gè)參數(shù) (container) 是 DOM 元素。
如何使用它在 React15.X 版本中,我們只能講子節(jié)點(diǎn)在父節(jié)點(diǎn)中渲染,基本用法如下:
render() { // React需要?jiǎng)?chuàng)建一個(gè)新的div來包含子節(jié)點(diǎn) return ({this.props.children}); }
但是如果需要將子節(jié)點(diǎn)插入到父節(jié)點(diǎn)之外的dom呢,React15.x 及之前都沒有提供這個(gè)功能的 API。
可以使用 React16.0 中的 portal:
render() { // React不需要?jiǎng)?chuàng)建一個(gè)新的div去包含子元素,直接將子元素渲染到另一個(gè) //dom節(jié)點(diǎn)中 //這個(gè)dom節(jié)點(diǎn)可以是任何有效的dom節(jié)點(diǎn),無論其所處于dom樹中的哪個(gè)位置 return ReactDOM.createPortal( this.props.children, domNode, ); }
Portal 的一個(gè)典型用例是這樣的:當(dāng)父組件帶有 overflow:hidden 或 z-index 樣式時(shí),你希望子組件在視覺上能夠“突破”它的容器。例如,對(duì)話框、懸停卡和工具提示。
點(diǎn)擊查看在線事例
自定義 DOM 屬性React15 會(huì)忽略任何未知的 DOM 屬性。React 會(huì)跳過它們,因?yàn)闊o法識(shí)別它們。
// 你的代碼
React 15 將渲染一個(gè)空的 div:
// React 15 output:
在 React16 中,輸出將如下所示(會(huì)顯示自定義屬性,并且完全不會(huì)被忽略)
// React 16 output:在 state 中設(shè)置 null 避免重新渲染
有時(shí)候我們需要通過函數(shù)來判斷組件狀態(tài)更新是否觸發(fā)重新渲染,在 React 16 中,我們可以通過調(diào)用 setState 時(shí)傳入 null 來避免組件重新渲染,這也就意味著,我們可以在 setState 方法內(nèi)部決定我們的狀態(tài)是否需要更新,
const MAX_PIZZAS = 20; function addAnotherPizza(state, props) { // Stop updates and re-renders if I"ve had enough pizzas. if (state.pizza === MAX_PIZZAS) { return null; } // If not, keep the pizzas coming! :D return { pizza: state.pizza + 1, } } this.setState(addAnotherPizza);
更多相關(guān)信息請(qǐng)閱讀這里
創(chuàng)建 ref現(xiàn)在使用 React16 創(chuàng)建refs要容易得多。 為什么需要使用refs:
管理焦點(diǎn)、文本選擇或媒體播放。
觸發(fā)動(dòng)畫。
與第三方 DOM 庫集成。
ref 是使用 React.createRef() 創(chuàng)建的,并通過 ref 屬性附加到 React 元素。ref 通常是在構(gòu)造組件時(shí)被分配給實(shí)例的屬性,以便在整個(gè)組件中引用它們。
class MyComponent extends React.Component { constructor(props) { super(props); this.myRef = React.createRef(); } render () { return } }訪問 ref
上述是創(chuàng)建Ref指向的方法, 在Ref 所指向的組件,在render后就可以調(diào)用,React16.3 中提供了current 屬性,用于引用render后的節(jié)點(diǎn):
componentDidMount(){ console.log(this.myRef.current); //render之后就可以輸出該ref指向的那個(gè)節(jié)點(diǎn) }
此外,同樣的 Ref 所指向的節(jié)點(diǎn)可以是 dom 節(jié)點(diǎn),也可以是類組件。
Ref 的值因節(jié)點(diǎn)的類型不同而有所不同:
當(dāng) ref 屬性用于 HTML 元素時(shí),在構(gòu)造函數(shù)中使用 React.createRef() 創(chuàng)建的 ref 將底層 DOM 元素作為 current 屬性。
當(dāng) ref 屬性用于自定義類組件時(shí),ref 對(duì)象將已掛載的組件實(shí)例作為 current 屬性。
你可能不會(huì)在功能組件上使用 ref 屬性,因?yàn)樗鼈儧]有實(shí)例。
Context APIContext 提供了一種通過組件樹傳遞數(shù)據(jù)的方法,無需在每一層手動(dòng)傳遞 prop。
React.createContextconst { Provider, Consumer } = React.createContext(defaultValue)
創(chuàng)建{Provider,Consumer}對(duì)。當(dāng) React 渲染 Consumer 時(shí),它將從樹中最接近的 Provider 讀取當(dāng)前上下文值。
defaultValue 參數(shù)只在消費(fèi)者在樹中找不到匹配的 Provider 時(shí)才會(huì)用到,這在多帶帶測試組件時(shí)十分有用。注意:將 undefined 作為 Provider 值傳遞進(jìn)去并不會(huì)導(dǎo)致 Consumer 使用 defaultValue。
Provider一個(gè)允許 Consumer 訂閱上下文變更的 React 組件。
一個(gè) Provider 可以連接多個(gè) Consumer,可以在樹中嵌套 Provider,實(shí)現(xiàn)更深的值覆蓋。
Consumer{value => /* render something based on the context value */}
訂閱上下文更改的 React 組件。
需要一個(gè)函數(shù)作為子組件。這個(gè)函數(shù)接收當(dāng)前上下文值,并返回一個(gè) React 節(jié)點(diǎn)。傳給函數(shù)的 value 參數(shù)將等于樹中最近的 Provider 的 value。如果沒有匹配的 Provider,則 value 參數(shù)將等于傳給 createContext() 的 defaultValue。
static getDerivedStateFromProps()在很長一段時(shí)間內(nèi),componentWillReceiveProps是在沒有附加渲染的情況下更新狀態(tài)的唯一方法。
在版本16.3中,我們引入了一個(gè)全新的生命周期函數(shù)getDerivedStateFromProps用來替換componentWillReceiveProps,并用更安全的方式處理相同的場景。
與此同時(shí),我們意識(shí)到人們對(duì)如何使用這兩種方法有很多誤解,我們發(fā)現(xiàn)了一些反模式,這些錯(cuò)誤導(dǎo)致了微妙而令人困惑的bug。
在16.4中,有關(guān)getDerivedStateFromProps的修復(fù)使得派生狀態(tài)更加可預(yù)測,因此錯(cuò)誤使用的結(jié)果更容易被注意到。
getDerivedStateFromProps 會(huì)在調(diào)用 render 方法之前被調(diào)用,它應(yīng)該返回一個(gè)用于更新狀態(tài)的對(duì)象,或者如果不更新任何狀態(tài)就返回 null。
這個(gè)方法適用于一些罕見的用例,其中 state 依賴 prop 的變化。例如,可以很方便地實(shí)現(xiàn)一個(gè)
衍生 state 會(huì)導(dǎo)致冗長的代碼,并讓你的組件難以開發(fā)和維護(hù)。
你可以考慮更簡單的替代方案:
如果你需要在 prop 發(fā)生變更時(shí)做一些其他事情(例如數(shù)據(jù)提取或動(dòng)畫),請(qǐng)改用 componentDidUpdate 生命周期。
如果你只想在 prop 發(fā)生變更時(shí)重新計(jì)算某些數(shù)據(jù),請(qǐng)改用 memoization helper:
* 如果你想在 prop 發(fā)生變更時(shí)“重置”某個(gè)狀態(tài),請(qǐng)考慮創(chuàng)建受控組件或帶有鍵的非受控組件。
此方法無權(quán)訪問組件實(shí)例。 如果你愿意,可以通過提取組件props的純函數(shù)和類定義之外的狀態(tài),在getDerivedStateFromProps() 和其他類方法之間重用一些代碼。
注意,不管怎樣,這個(gè)方法都會(huì)在每次進(jìn)行渲染時(shí)觸發(fā)。這與 UNSAFE_componentWillReceiveProps 完全相反。它只在父組件進(jìn)行重新渲染時(shí)觸發(fā),而且不作為本地 setState 的結(jié)果。
將nextProps.someValue與this.props.someValue進(jìn)行比較。 如果兩者都不同,那么我們執(zhí)行一些操作:
static getDerivedStateFromProps(nextProps, prevState){ if(nextProps.someValue!==prevState.someValue){ return { someState: nextProps.someValue}; } return null }
它接收兩個(gè)參數(shù) nextProps 和 prevState。如前所述,你無法在這個(gè)方法中訪問 this。你必須將 prop 存儲(chǔ)在 state 中,然后將 nextProps 與之前的 prop 進(jìn)行對(duì)比。在上面的代碼中,nextProps 和 prevState 進(jìn)行了比較。如果兩者不同,則返回一個(gè)用于更新狀態(tài)的對(duì)象,否則就返回 null,表示不需要更新狀態(tài)。如果 state 發(fā)生變更,就會(huì)調(diào)用 componentDidUpdate,我們可以像在 componentWillReceiveProps 中那樣執(zhí)行所需的操作。
React 生命周期事件react v16.3,最大的變動(dòng)莫過于生命周期去掉了以下三個(gè):
componentWillMount
componentWillReceiveProps
componentWillUpdate
同時(shí)為了彌補(bǔ)失去上面三個(gè)周期的不足又加了兩個(gè):
static getDerivedStateFromProps
getSnapshotBeforeUpdate
為什么要改舊的生命周期十分完整,基本可以捕捉到組件更新的每一個(gè)state/props/ref,沒有什從邏輯上的毛病。
但是架不住官方自己搞事情,react打算在17版本推出新的Async Rendering,提出一種可被打斷的生命周期,而可以被打斷的階段正是實(shí)際dom掛載之前的虛擬dom構(gòu)建階段,也就是要被去掉的三個(gè)生命周期。
生命周期一旦被打斷,下次恢復(fù)的時(shí)候又會(huì)再跑一次之前的生命周期,因此componentWillMount,componentWillReceiveProps, componentWillUpdate 都不能保證只在掛載/拿到props/狀態(tài)變化的時(shí)候刷新一次了,所以這三個(gè)方法被標(biāo)記為不安全。
你的點(diǎn)贊是我持續(xù)分享好東西的動(dòng)力,歡迎點(diǎn)贊!
歡迎加入前端大家庭,里面會(huì)經(jīng)常分享一些技術(shù)資源。文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109456.html
摘要:譯者前端小智原文就像人們對(duì)更新移動(dòng)應(yīng)用程序和操作系統(tǒng)感到興奮一樣,開發(fā)人員也應(yīng)該對(duì)更新框架感到興奮。錯(cuò)誤邊界是一種組件。注意將作為值傳遞進(jìn)去并不會(huì)導(dǎo)致使用。如果兩者不同,則返回一個(gè)用于更新狀態(tài)的對(duì)象,否則就返回,表示不需要更新狀態(tài)。 譯者:前端小智 原文:medium.freecodecamp.org/why-react16… 就像人們對(duì)更新移動(dòng)應(yīng)用程序和操作系統(tǒng)感到興奮一樣,開發(fā)人員也應(yīng)...
摘要:協(xié)調(diào)狀態(tài)的這三個(gè)方面是前端開發(fā)的重要組成部分,對(duì)這項(xiàng)任務(wù)有不同程度的支持。這使得保持高度統(tǒng)一。的真正威力到目前為止,看上去只是的輔助工具。在的術(shù)語中這稱之為派發(fā)動(dòng)作。撤銷重做流行的撤銷重做功能需要系統(tǒng)級(jí)規(guī)劃。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來篇優(yōu)質(zhì)文章等著你! 你知道 Redux 真正的作用遠(yuǎn)不止?fàn)顟B(tài)管理嗎? 你是否想要了解 Redux 的工作原理? 讓我們深入研究 ...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。將整個(gè)應(yīng)用打包發(fā)布,自動(dòng)試用進(jìn)行壓縮與優(yōu)化。毫無疑問,這些重?fù)?dān)都將壓在企業(yè)開發(fā)人員身上團(tuán)隊(duì)之間如何高效協(xié)調(diào),快速交付產(chǎn)品,快速部署應(yīng)用,以及滿足企業(yè)業(yè)務(wù)需求,是開發(fā)人員亟需解決的問題。 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Red...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。將整個(gè)應(yīng)用打包發(fā)布,自動(dòng)試用進(jìn)行壓縮與優(yōu)化。毫無疑問,這些重?fù)?dān)都將壓在企業(yè)開發(fā)人員身上團(tuán)隊(duì)之間如何高效協(xié)調(diào),快速交付產(chǎn)品,快速部署應(yīng)用,以及滿足企業(yè)業(yè)務(wù)需求,是開發(fā)人員亟需解決的問題。 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Red...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。將整個(gè)應(yīng)用打包發(fā)布,自動(dòng)試用進(jìn)行壓縮與優(yōu)化。毫無疑問,這些重?fù)?dān)都將壓在企業(yè)開發(fā)人員身上團(tuán)隊(duì)之間如何高效協(xié)調(diào),快速交付產(chǎn)品,快速部署應(yīng)用,以及滿足企業(yè)業(yè)務(wù)需求,是開發(fā)人員亟需解決的問題。 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Red...
閱讀 1876·2021-09-28 09:36
閱讀 2426·2021-09-08 09:35
閱讀 3066·2019-08-30 15:53
閱讀 1553·2019-08-30 14:08
閱讀 664·2019-08-29 18:40
閱讀 2842·2019-08-29 13:57
閱讀 2702·2019-08-29 13:55
閱讀 681·2019-08-26 13:45