最近(2018-10-23)React官方釋出了16.6
版本,開放了一堆新的功能,而這其中的一些新功能,代表這未來的React開發方式,讓我們來一起窺探未來吧。
lazy
最讓人期待的功能肯定就是lazy
功能了,配合釋出了一個Suspense
元件,也就是最開始命名為Placeholder
的元件,用來配合render
方法內部的非同步操作的,讓我們先來看一下lazy
的用法
import React, {lazy, Suspense} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
);
}
複製程式碼
做過code-splitting
的同學能聞到熟悉的味道。以前我們要用第三方包或者自己處理非同步過程,現在,React原生支援啦,而且你可以把非同步的過程直接扔到render
方法裡面,就跟寫普通元件一樣,而且可以方便得通過Suspense
元件來提供fallback
然而這並不僅僅Suspense
的唯一用處,事實上這次React正式開放Suspense
元件代表著所有非同步的操作都可以在render
方法裡面做了,其實我很意外,我以為正式開放肯定要等到17版本
那麼非同步操作還能做啥?如果同學們看過年初Dan在冰島的分享,應該就知道,Suspense
能夠讓我們載入資料的操作變得異常簡單。沒看過的同學可以看這裡,現在npm上也有一個包提供資料載入的功能了,simple-cache-provider,但是現在還不要在正式環境使用他哦。
關於這部分如何實現的,我會在之後的原始碼分析上詳細講解,有興趣的同學可以關注我。
React.memo
ClassComponent
可以通過繼承類PureComponent
或者實現shouldComponentUpdate
來主動判斷元件是否需要重新渲染,以此來提高效能,但是FunctionalComponent
到目前為止沒有類似的功能。
所以今天React釋出了React.memo
方法,來實現類似PureComponent
的功能,即淺比較props
是否有變化,如果沒有變化,就不重新渲染當前元件
const FunctionalComponent = React.memo((props) => {
// only render if props change
})
複製程式碼
static contextType
在React16.3中提供了我們一個標準的用於替代老的context
的API,也就是React.createContext
,然後通過context.Provider
和context.Consumer
來傳遞值,這種方式消除了老的context
API效能低下的問題,這個問題我在之前也有詳細分析,感興趣的同學可以看這裡,而且老的API程式碼量很多,所以下個大版本React會移除老的API。
但是在讓生態外掛升級到新的API的過程中,有人提出在ClassComponent
中用新的API很麻煩(???沒感覺啊),所以React提供了一種在ClassComponent
中使用新API的方法
import React, { Component } from 'react';
const context = React.createContext('defaultValue')
const ProviderComp = ({ children }) => (
<context.Provider value="provider">
{children}
</context.Provider>
)
class ConsumerComp extends Component {
static contextType = context
componentDidMount() {
console.log(this.context)
}
render() {
return (
<p>{this.context}</p>
)
}
}
class App extends Component {
render() {
return (
<ProviderComp>
<ConsumerComp />
</ProviderComp>
);
}
}
複製程式碼
通過宣告static contextType = context
,讓ClassComponent
可以訂閱最近的一個context provider
,注意這裡contextType
是固定宣告,換成別的名字都不行。如果ConsumerComp
不在Provider
的子樹中,那麼會使用defaultValue
class App extends Component {
render() {
return (
<>
<ProviderComp />
<ConsumerComp /> // show default value
</>
);
}
}
複製程式碼
這也是為了提高React的整體效能,移除老舊API做努力。
static getDerivedStateFromError()
在釋出Error Boundaries
的時候,React提供了一個新的生命週期方法componentDidCatch
,在捕獲到錯誤的時候會觸發,你可以在裡面修改state
以顯示錯誤提醒的UI,或者將錯誤資訊傳送給服務端進行log
用於後期分析。但是這裡有個問題,就是在捕獲到錯誤的瞬間,React會在這次渲染週期中將這個元件渲染為null
,這就有可能導致他的父元件設定他上面的ref
獲得null
而導致一些問題,所以現在提供了這個方法。
這個方法跟getDerivedStateFromProps
類似,唯一的區別是他只有在出現錯誤的時候才觸發,他相對於componentDidCatch
的優勢是在當前的渲染週期中就可以修改state
,以在當前渲染就可以出現錯誤的UI,而不需要一個null
的中間態。
而這個方法的出現,也意味著以後出現錯誤的時候,修改state
應該放在這裡去做,而後續收集錯誤資訊之類的放到componentDidCatch
裡面。
StrictMode下的新提醒
StrictMode
是用來提醒開發者用了即將被廢棄的API的,像componentWillMount
這些宣告週期都會提醒,這次新加了兩個API的提醒,ReactDOM.findDOMNode()
,和老的context api
。
也代表著這兩個下個大版本肯定會被移除。所以兄弟們還不趕緊更新!
我是Jocky,一個專注於React技巧和深度分析的前端工程師,React絕對是一個越深入學習,越能讓你覺得他的設計精巧,思想超前的框架。關注我獲取最新的React動態,以及最深度的React學習。更多的文章看這裡