今天我們釋出了 React 16.9。它包含了一些新特性、bug修復以及新的棄用警告,以便與籌備接下來的主要版本。
一、新棄用
重新命名 Unsafe 生命週期方法
一年前,我們宣佈 unsafe 生命週期方法重新命名為:
-
componentWillMount
→UNSAFE_componentWillMount
-
componentWillReceiveProps
→UNSAFE_componentWillReceiveProps
-
componentWillUpdate
→UNSAFE_componentWillUpdate
React v16.9 不包含破壞性更改,而且舊的生命週期方法在此版本依然沿用。但是,當你在新版本中使用舊的生命週期方法時,會提示如下警告:
正如警告所示,對於每種 unsafe 的方法,通常有更好的解決方案。但你可能沒有過多時間去遷移或測試這些元件。在這種情況下,我們建議執行一個自動重新命名它們的 codemod 指令碼:
cd your_project
npx react-codemod rename-unsafe-lifecycles
(注意:這裡使用的是 npx
,不是 npm
,npx
是 Node 6+ 預設提供的實用程式。)
執行 codemod 將會替換舊的生命週期,如 componentWillMount
將會替換為 UNSAFE_componentWillMount
:
新命名的生命週期(例如: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 專案中的任意一個子樹上,來測量該子樹的渲染成本。它需要兩個 props
:id
(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...
走在最後,歡迎關注:前端瓶子君