幾天前,我們寫了一篇關於即將到來的對我們的傳統生命週期方法的變更的文章,包括逐步遷移策略。在React 16.3.0中,我們加入了一些新的生命週期方法來幫助遷移。我們還引入了新的API,用於長時間請求的特性:一個官方的上下文API、一個ref轉發API和一個更語義化的ref API。
請繼續閱讀,以了解更多關於這個版本的資訊。
多年來,React為Context提供了一個實驗性的API。雖然它是一個強大的工具,但由於API中固有的問題,它的使用是不受歡迎的,因此我們打算用更好的API來取代這個實驗性的API。
React 16.3引入了一個新的Context API,它更有效率,同時支援靜態類型檢查和深度更新。
注意
舊的ContextAPI 將繼續保留到React 16.x,所以您將有時間遷移。
下面是一個範例,說明如何使用新的上下文API注入「主題」:
## by 司徒正美 const ThemeContext = React.createContext('light'); class ThemeProvider extends React.Component { state = {theme: 'light'}; render() { return ( <ThemeContext.Provider value={this.state.theme}> {this.props.children} </ThemeContext.Provider> ); } } class ThemedButton extends React.Component { render() { return ( <ThemeContext.Consumer> {theme => <Button theme={theme} />} </ThemeContext.Consumer> ); } }
以前,React提供了兩種管理refs的方法:字串ref API和回調ref API。儘管字串ref API比較方便,但它有幾個缺點,所以我們的官方推薦是使用回調ref。
React 16.3為管理refs提供了一個新的方案,它為字串ref提供了方便,並且沒有任何缺點:
## by 司徒正美 class MyComponent extends React.Component { constructor(props) { super(props); this.inputRef = React.createRef(); } render() { return <input type="text" ref={this.inputRef} />; } componentDidMount() { this.inputRef.current.focus(); } }
注意除了新的createRef API外,回呼refs將繼續獲得支援。
您不需要在元件中取代回呼refs。它們稍微靈活一些,因此它們將繼續作為一個高級特性。
高階元件(或HOCs)是在元件之間重複使用程式碼的常用方法。基於上面的主題上下文範例,我們可能會建立一個臨時對象,將目前的「主題」作為一個屬性注入:
## by 司徒正美 function withTheme(Component) { return function ThemedComponent(props) { return ( <ThemeContext.Consumer> {theme => <Component {...props} theme={theme} />} </ThemeContext.Consumer> ); }; }
我們可以使用上述特殊的方式將元件連接到主題上下文,而不必直接使用主題上下文。例如:
## by 司徒正美 class FancyButton extends React.Component { buttonRef = React.createRef(); focus() { this.buttonRef.current.focus(); } render() { const {label, theme, ...rest} = this.props; return ( <button {...rest} className={`${theme}-button`} ref={this.buttonRef}> {label} </button> ); } } const FancyThemedButton = withTheme(FancyButton); // We can render FancyThemedButton as if it were a FancyButton // It will automatically receive the current "theme", // And the HOC will pass through our other props. <FancyThemedButton label="Click me!" onClick={handleClick} />;
HOCs通常會將props傳遞給它們包裝的組件。不幸的是,refs沒有沖透進去。這意味著如果我們使用FancyThemedButton,我們就不能將ref新增到FancyButton中,因此我們無法呼叫focus()。
新的代理API透過提供一種方法來攔截一個ref,並將其轉發為一個普通的props,從而解決了這個問題:
## by 司徒正美 function withTheme(Component) { // Note the second param "ref" provided by React.forwardRef. // We can attach this to Component directly. function ThemedComponent(props, ref) { return ( <ThemeContext.Consumer> {theme => ( <Component {...props} ref={ref} theme={theme} /> )} </ThemeContext.Consumer> ); } // These next lines are not necessary, // But they do give the component a better display name in DevTools, // e.g. "ForwardRef(withTheme(MyComponent))" const name = Component.displayName || Component.name; ThemedComponent.displayName = `withTheme(${name})`; // Tell React to pass the "ref" to ThemedComponent. return React.forwardRef(ThemedComponent); } const fancyButtonRef = React.createRef(); // fancyButtonRef will now point to FancyButton <FancyThemedButton label="Click me!" onClick={handleClick} ref={fancyButtonRef} />;
React的類別元件API已經存在多年,幾乎沒有變化。但是,當我們為更高級的特性(例如錯誤邊界和即將到來的非同步渲染模式)添加支援時,我們以它本來沒有打算的方式來擴展這個模型。
例如,在目前的API中,用一些非尋常的手段來阻止初始渲染是很容易的。在某種程度上,這是因為有太多的鉤子來完成這項既定的任務,而且還不清楚哪一個是最好的。我們已經注意到錯誤處理的中斷行為通常不會被考慮,並且可能導致記憶體洩漏(這也會影響即將到來的非同步渲染模式)。目前的類別組件API也使其他的工作變得複雜,例如我們的程式碼優化器(Prepack)的工作。
componentWillMount
, componentWillReceiveProps
, componentWillUpdate
這些鉤子很容易引發問題,也嚴重擾亂React的生命週期。基於這些原因,我們將放棄這些方法,以支持更好的替代方案。
我們認識到這項變更將影響許多現有的元件。因此,遷移路徑將盡可能平緩,並提供遷移方案。 (在Facebook,我們擁有5萬多個React元件。我們也依賴一個漸進的發布週期!
#注意棄用警告將在React16以後的版本中啟用, 一直保留到17發佈時。現有程式碼中重新命名它們。 # 用來componentWillReceiveProps。 ;StrictMode />
是一種專門用於暴露潛在問題的工具。渲染到視圖中。模式下運作;它們不會影響生產建置。的模式下看到警告,這些事情很可能會導致非同步渲染的錯誤。在16.3版本中,StrictMode幫助:
識別具有不安全生命週期鉤子的元件。
關於遺留字串ref API用法的警告。
偵測意想不到的副作用
#######################################################################
以上是React v16.3.0:新的生命週期和情境 API的詳細內容。更多資訊請關注PHP中文網其他相關文章!