[譯]React v16.9 新特性

瓶子君發表於2019-08-15

今天我們釋出了 React 16.9。它包含了一些新特性、bug修復以及新的棄用警告,以便與籌備接下來的主要版本。

一、新棄用

重新命名 Unsafe 生命週期方法

一年前,我們宣佈 unsafe 生命週期方法重新命名為:

  • componentWillMountUNSAFE_componentWillMount
  • componentWillReceivePropsUNSAFE_componentWillReceiveProps
  • componentWillUpdateUNSAFE_componentWillUpdate

React v16.9 不包含破壞性更改,而且舊的生命週期方法在此版本依然沿用。但是,當你在新版本中使用舊的生命週期方法時,會提示如下警告:

Warning:componentWillMount has been renamed,and is not recommended for use.

正如警告所示,對於每種 unsafe 的方法,通常有更好的解決方案。但你可能沒有過多時間去遷移或測試這些元件。在這種情況下,我們建議執行一個自動重新命名它們的 codemod 指令碼:

cd your_project
npx react-codemod rename-unsafe-lifecycles

(注意:這裡使用的是 npx,不是 npmnpx 是 Node 6+ 預設提供的實用程式。)

執行 codemod 將會替換舊的生命週期,如 componentWillMount 將會替換為 UNSAFE_componentWillMount :

Codemode in action

新命名的生命週期(例如:UNSAFE_componentWillMount)在 React 16.9 和 React 17.x 繼續使用,但是,新的 UNSAFE_ 字首將幫助具有問題的元件在程式碼 review 和 debugging 期間脫穎而出。(如果你不喜歡,你可以引入 嚴格模式(Strict Mode)來進一步阻止開發人員使用它 。)

點選此連結,學習更多關於 版本策略以及穩定性承諾

棄用:javascript: URLs

javascript: 開頭的 URL 很容易遭受攻擊,因為它很容易意外在標籤中(<a href>)引入未經處理的輸出,造成安全漏洞。

const userProfile = {
  website: "javascript: alert('you got hacked')",
};
// This will now warn:
<a href={userProfile.website}>Profile</a>

在 React 16.9 中,這種模式將繼續有效,但它將輸出一個警告,如果你邏輯上需要使用 javascript: 開頭的 URL,請嘗試使用 React 事件處理程式代替。(萬不得已,你可以使用 dangerouslySetInnerHTML 來規避保護,但仍然是不鼓勵使用的並且往往會導致安全漏洞。)

在未來的主要版本中,如果遇到 javascript: 形式的 URL,React 將丟擲錯誤。

棄用 “Factory” 元件

在用 Babel 編譯 JavaScript 類流行前,React 支援 “factory” 元件,它使用 render 方法返回一個物件。

function FactoryComponent() {
  return { render() { return <div />; } }
}

這種模式令人困惑,因為它看起來太像一個函式元件,但它不是一個。(函式元件只會返回像上述示例中的 <div /> )。

這種模式幾乎從未在外部使用過,並且支援它會導致 React 變大、變慢。因此,我們在 16.9 中棄用此模式,並且遇到時,輸出警告。如果你在專案中依賴此元件,可以新增 FactoryComponent.prototype = React.Component.prototype 作為解決方法。或者,你可以將它轉換為 class 元件或函式元件。

我們預計大多數程式碼庫不會受此影響。

二、新特性

用於測試的一部函式 act()

React 16.8 引入了名為 act() 的新測試實用程式來幫助你編寫更匹配瀏覽器行為的測試程式碼。例如,對單個 act() 中的多個狀態更新進行批處理。這與 React 已有的處理真實瀏覽器事件時的工作方式相匹配,並有助於為將來 React 元件更頻繁地批處理更新做準備。

然而,React v16.8 中的 act() 僅支援同步函式,有時,你可能在測試環境下看到以下警告,但無法輕易修復:

An update to SomeComponent inside a test was not wrapped in act(...).

在 React 16.9 中 act() 支援非同步函式 ,你可以在呼叫它時,使用 await

await act(async () => {
  // ...
});

這將解決以前無法使用 act() 的情況,例如當 state 更新位於非同步函式中時。因此,你現在應該能夠測試中修復所有關於 act() 的警告了

我們聽說,現在還沒有足夠的資訊關於如何使用 act() 編寫測試用例。新的測試技巧指南介紹了一些常見方案,以及 act() 如何幫助您編寫良好的測試。這些示例使用原生 DOM API,但您也可以使用 React Testing Library 來減少樣板程式碼。它的許多方法已經在內部使用 act()

如果你遇到 act() 的相關問題,請在問題跟蹤器上告知我們,我們會盡力提供幫助。

使用 <React.Profiler> 進行效能評估

在 React 16.5 中,我們介紹了新的 React Profiler for DevTools 來幫助開發人員發現專案中的效能瓶頸。在 React 16.9 中,我們提供了一種程式設計的方式來收集測量你的程式碼,這就是 <React.Profiler> ,我們預計大多數較小的應用不會使用它,但在大型應用中跟蹤效能迴歸會很方便。

<Profiler> 測量 React 應用程式渲染的頻率以及渲染的 "成本" 。其目的是幫助識別應用程式中渲染緩慢的部分,並且可能更益與 memoization 等優化

可以將 <Profiler> 新增到 React 專案中的任意一個子樹上,來測量該子樹的渲染成本。它需要兩個 propsid (string) 和 onRender 回撥(function),當樹中的元件"提交"更新時,React 將呼叫它。

render(
  <Profiler id="application" onRender={onRenderCallback}>
    <App>
      <Navigation {...props} />
      <Main {...props} />
    </App>
  </Profiler>
);

要了解關於 Profiler 和傳遞給 onRender 回撥的引數的更多詳細資訊,請檢視 Profiler 文件

注意:

Profiling 會增加一些額外的開銷,因此在生產構建中禁止使用它。

如果想要在生產環境中進行效能分析,React 提供了特殊的生產構建,並啟用了分析模式。在 fb.me/react-profiling 閱讀更多關於如何使用此構建的更多資訊。

三、顯著的 bug 修復

此版本包含一些一些其他顯著的提升:

  • <Suspense> 元件中呼叫 findDOMNode() 造成崩潰,已修復
  • 儲存已刪除的子樹導致記憶體洩漏,已修復
  • useEffect 中,使用 setState 引起的迴圈引用,現在會輸出錯誤(這與在 class 元件中的 componentDidUpdate 使用 setState 導致的錯誤一致)

感謝所有幫助解決這些問題的貢獻者,你可以在此處找到完整的日誌。

本文翻譯自:https://reactjs.org/blog/2019...

走在最後,歡迎關注:前端瓶子君
前端瓶子君

相關文章