react如何開啟嚴格模式

react如何開啟嚴格模式

StrictMode 是一個用來突出顯示應用程序中潛在問題的工具。與 Fragment 一樣,StrictMode 不會渲染任何可見的 UI。它為其後代元素觸發額外的檢查和警告。

注意:

嚴格模式檢查僅在開發模式下運行;它們不會影響生產構建。

你可以為應用程序的任何部分啟用嚴格模式。例如:

import React from 'react';

function ExampleApplication() {

return (

<header>

<react.strictmode>

<componentone>

<componenttwo>

<footer>

);

}

在上述的示例中,不會對 Header 和 Footer 組件運行嚴格模式檢查。但是,ComponentOne 和 ComponentTwo 以及它們的所有後代元素都將進行檢查。

StrictMode 目前有助於:

  • 識別不安全的生命週期
  • 關於使用過時字符串 ref API 的警告
  • 關於使用廢棄的 findDOMNode 方法的警告
  • 檢測意外的副作用
  • 檢測過時的 context API

未來的 React 版本將添加更多額外功能。

識別不安全的生命週期

正如這篇博文所述,某些過時的生命週期方法在異步 React 應用程序中使用是不安全的。但是,如果你的應用程序使用了第三方庫,很難確保它們不使用這些生命週期方法。幸運的是,嚴格模式可以幫助解決這個問題!

當啟用嚴格模式時,React 會列出使用了不安全生命週期方法的所有 class 組件,並打印一條包含這些組件信息的警告消息,如下所示:

react如何開啟嚴格模式

strict mode unsafe lifecycles warning

此時解決項目中嚴格模式所識別出來的問題,會使得在未來的 React 版本中使用異步渲染變得更容易。

關於使用過時字符串 ref API 的警告

以前,React 提供了兩種方法管理 refs 的方式:已過時的字符串 ref API 的形式及回調函數 API 的形式。儘管字符串 ref API 在兩者中使用更方便,但是它有一些缺點,因此官方推薦採用回調的方式。

React 16.3 新增了第三種選擇,它提供了使用字符串 ref 的便利性,並且不存在任何缺點:

class MyComponent extends React.Component {

constructor(props) {

super(props);

this.inputRef = React.createRef();

}

render() {

return ;

}

componentDidMount() {

this.inputRef.current.focus();

}

}

由於對象 ref 主要是為了替換字符串 ref 而添加的,因此嚴格模式現在會警告使用字符串 ref。

注意:

除了新增加的 createRef API,回調 ref 依舊適用。

你無需替換組件中的回調 ref。它們更靈活,因此仍將作為高級功能保留。

在此處瞭解有關 createRef API 的更多信息

關於使用廢棄的 findDOMNode 方法的警告

React 支持用 findDOMNode 來在給定 class 實例的情況下在樹中搜索 DOM 節點。通常你不需要這樣做,因為你可以將 ref 直接綁定到 DOM 節點。

findDOMNode 也可用於 class 組件,但它違反了抽象原則,它使得父組件需要單獨渲染子組件。它會產生重構危險,你不能更改組件的實現細節,因為父組件可能正在訪問它的 DOM 節點。findDOMNode 只返回第一個子節點,但是使用 Fragments,組件可以渲染多個 DOM 節點。findDOMNode 是一個只讀一次的 API。調用該方法只會返回第一次查詢的結果。如果子組件渲染了不同的節點,則無法跟蹤此更改。因此,findDOMNode 僅在組件返回單個且不可變的 DOM 節點時才有效。

你可以通過將 ref 傳遞給自定義組件並使用 ref 轉發來將其傳遞給 DOM 節點。

你也可以在組件中創建一個 DOM 節點的 wrapper,並將 ref 直接綁定到它。

class MyComponent extends React.Component {

constructor(props) {

super(props);

this.wrapper = React.createRef();

}

render() {

return

{this.props.children}
;

}

}

注意:

在 CSS 中,如果你不希望節點成為佈局的一部分,則可以使用 display: contents 屬性。

檢測意外的副作用

從概念上講,React 分兩個階段工作:

  • 渲染 階段會確定需要進行哪些更改,比如 DOM。在此階段,React 調用 render,然後將結果與上次渲染的結果進行比較。
  • 提交 階段發生在當 React 應用變化時。(對於 React DOM 來說,會發生在 React 插入,更新及刪除 DOM 節點的時候。)在此階段,React 還會調用 componentDidMount 和 componentDidUpdate 之類的生命週期方法。

提交階段通常會很快,但渲染過程可能很慢。因此,即將推出的異步模式 (默認情況下未啟用) 將渲染工作分解為多個部分,對任務進行暫停和恢復操作以避免阻塞瀏覽器。這意味著 React 可以在提交之前多次調用渲染階段生命週期的方法,或者在不提交的情況下調用它們(由於出現錯誤或更高優先級的任務使其中斷)。

渲染階段的生命週期包括以下 class 組件方法:

  • constructor
  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • setState 更新函數(第一個參數)

因為上述方法可能會被多次調用,所以不要在它們內部編寫副作用相關的代碼,這點非常重要。忽略此規則可能會導致各種問題的產生,包括內存洩漏和或出現無效的應用程序狀態。不幸的是,這些問題很難被發現,因為它們通常具有非確定性。

嚴格模式不能自動檢測到你的副作用,但它可以幫助你發現它們,使它們更具確定性。通過故意重複調用以下方法來實現的該操作:

  • class 組件的 constructor 方法
  • render 方法
  • setState 更新函數 (第一個參數)
  • 靜態的 getDerivedStateFromProps 生命週期方法

注意:

這僅適用於開發模式。生產模式下生命週期不會被調用兩次。

例如,請考慮以下代碼:

class TopLevelRoute extends React.Component {

constructor(props) {

super(props);

SharedApplicationState.recordEvent('ExampleComponent');

}

}

這段代碼看起來似乎沒有問題。但是如果 SharedApplicationState.recordEvent 不是冪等的情況下,多次實例化此組件可能會導致應用程序狀態無效。這種小 bug 可能在開發過程中可能不會表現出來,或者說表現出來但並不明顯,並因此被忽視。

嚴格模式採用故意重複調用方法(如組件的構造函數)的方式,使得這種 bug 更容易被發現。

檢測過時的 context API

過時的 context API 容易出錯,將在未來的主要版本中刪除。在所有 16.x 版本中它仍然有效,但在嚴格模式下,將顯示以下警告:

react如何開啟嚴格模式


分享到:


相關文章: