1. 程式人生 > >React v16.3.0:新的生命週期和上下文API

React v16.3.0:新的生命週期和上下文API

官方提供:在React 16.3.0中, 我們正在新增一些新的生命週期方法來輔助遷移。我們還為長期被要求的功能引入了新的API: 一個官方的context API,一個轉發的ref API和一個更符合人類使用的ref API.

官方 Context API

多年來,React僅提供了一個實驗性的context API。儘管它是一個非常強大的API,但是,因為它固有問題以及我們打算用一個更好的API來替換這個實驗的API,所以這個API一般不被推薦使用。

版本16.3引入了一個新的context API,它非常高效並且支援靜態型別檢查和深度更新。

注意: 舊的context API將繼續適用於所有React 16.x版本,所以你將有足夠的時間進行遷移。

下面是一個例子,說明如何使用新的context API注入一個『theme』:

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>` ); } }

createRef API

先前, React 提交供了兩種管理refs的方法:傳統的字串形式API和回撥函式API。儘管字串引用API是兩者中使用最方便的,但它也有幾個缺點 ,所有我們官方的建議是使用回撥函式形式代替它。

版本16.3增加了一個管理refs的新的選項,它提供了使用字串形式ref的便利性而且沒有任務缺點:

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,Callback refs 將會繼續得到支援。
你沒有必要替換掉你元件中的callback refs。它們稍微的更靈活一點,所以它們仍然是一個比較先進的功能。

forwardRef API

高階元件 (or HOCs) 是在元件間複用的程式碼的常用方法。基於上面的主題背景示例,我們中以建立一個HOC,它以屬性的方式將當前『theme』進行注入:

function withTheme(Component) {
  return function ThemedComponent(props) {
    return (
      `<ThemeContext.Consumer>`
        {theme => `<Component {...props} theme={theme} />`}
      `</ThemeContext.Consumer>`
    );
  };
}

我們可以使用上面的HOC將元件直接連線到主體上下文,而無需直接使用 ThemeContext。例如:

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);

// 我們可以渲染FancyThemedButton,就好像它是一個FancyButton
// 它將會自動接收當前『theme』,
// 同時HOC也會傳遞我們其它的props。
`<FancyThemedButton
  label="Click me!"
  onClick={handleClick}
/>`;

HOCs通常將會把props傳遞給它們包裹著的元件。不幸的是, refs不會被傳遞。這意味著,如果我們使用FancyThemedButton,我們將無法通過refFancyButton進行連線,所以我們無法呼叫focus()

新的forwardRef API解決了這個問題,它提供了一個方法來攔截ref,並將它作為了普通的prop進行傳遞:

function withTheme(Component) {
  function ThemedComponent({forwardedRef, ...rest}) {
    return (
      `<ThemeContext.Consumer>`
        {theme => (
          // Assign the custom prop "forwardedRef" as a ref
          `<Component
            {...rest}
            ref={forwardedRef}
            theme={theme}
          />`
        )}
      `</ThemeContext.Consumer>`
    );
  }

  // 注意第二個引數"ref"是由React.forwardRef提供的。
  // 我們可以將它作為變通的props傳遞給ThemedComponent,例如 "forwardedRef"
  // 然後它可以被連線到這個元件。
  return React.forwardRef((props, ref) => (
    `<ThemedComponent {...props} forwardedRef={ref} />`
  ));
}

// 在這裡,我們假設FancyButton已經被匯入到當前上下文
const FancyThemedButton = withTheme(FancyButton);

// 通過Referenace API建立一個ref,
const fancyButtonRef = React.createRef();

// fancyButtonRef 現在指向 FancyButton
`<FancyThemedButton
  label="Click me!"
  onClick={handleClick}
  ref={fancyButtonRef}
/>`;

元件生命週期變更

React類元件的API已經有好多年了,而且幾乎沒有變化。但是,當我們新增對更高階功能的支援時(比如錯誤邊界和即將到來的非同步渲染模式),我們會以不是我們想要的方式來擴充套件此模型。

例如,使用當前的API,可以很容易的阻止非必要的邏輯進行初始渲染。部分原因是因為完成某項任務的方式太多,而且哪一個最好也不清楚。我們已經觀察到錯誤中斷的處理行通常不被考慮在內,並且可能導致記憶體洩漏(它會影響到即將到來的非同步渲染模式)。目前的類元件API也使其他工作複雜化,就像我們在原型化React編譯器方面的工作一樣。

這些問題在元件生命週期(componentWillMount, componentWillReceiveProps, and componentWillUpdate)的一個子集中更加的惡化。這些也恰好是造成React社群最混亂的生命週期問題。出於這些原因的考慮,我們將會降低這些方法的使用,轉而使用更好的方法代替。

我們意識到這些變更將會影響到現有的元件。因此,遷移路徑將會是漸進式的,並且會提供補救措施。(在Facebook上,我們維護了超過50,000個React元件。 我們也依賴於一個漸進的釋出週期! )

注意:
棄用警告將在未來的16.x版本中啟用,但舊版生命週期將繼續執行至17.x版。

使在17.x版中,仍然可以使用它們,但它們會以『UNSAFE_』為字首被重新命名,以表明它們可能會引起問題。我們還準備了一個自動化的指令碼來在現有程式碼中對它們重新命名。

除了摒棄不安全的生命週期外,我們還增加了一些新的生命週期:
- getDerivedStateFromProps 是一個比較安全的方法來替代以前 componentWillReceiveProps.
- getSnapshotBeforeUpdate 用於更安全的讀取屬性,比如在更新之前獲取DOM。
瞭解更多關於生命週期的變更

StrictMode Component

StrictMode是一個突出顯示應用潛在問題的工具。像Fragment一樣,StrictMode不會呈現任何可見的UI。它會為子元件作額外的檢查併發出警告。

注意:
StrictMode 檢查僅僅執行在開發模式下; 它們不影響生產構建

儘管在嚴格模式下不可能捕獲所有的問題(例如:某些型別的突變),但在它在大多數情況下還是很有用的。如果你在嚴格模式下看到警告,這些東西可能會引起非同步渲染的錯誤。

在16.3版中,StrictMode提供以下幫助:
- 識別不安全的生命週期元件
- 對使用字串ref API進行警告
- 檢測潛在副作用

相關推薦

React v16.3.0生命週期上下文API

官方提供:在React 16.3.0中, 我們正在新增一些新的生命週期方法來輔助遷移。我們還為長期被要求的功能引入了新的API: 一個官方的context API,一個轉發的ref API和一個更符合人類使用的ref API. 官方 Conte

react生命週期API3.0)及生命週期與定時器的用法;

react的定時器的呼叫必須採用元件生命週期函式去呼叫: 有關元件的生命週期,見菜鳥教程: http://www.runoob.com/react/react-component-life-cycle

Java8特性之的日期時間API

java8 時間日期API 一. LocalDate、LocalTime、Instant、Duration以及Period 1.LocalDate只提供日期,不含當天時間信息LocalDate date = LocalDate.of(2018, 5, 03); int year = da

React v15到v16.3, v16.4生命週期總結以及使用場景

前言 真正在專案中用到React,正是React版本從15到16.3(專案當前使用版本)又到16.4的變化期。React從15到16最令人困惑的改變莫過於生命週期函式的劇烈變動,由此引發的一些新的實踐方法。事實上,我們專案在從15升級到16,在生命

React v16.3生命週期

變更的部分react v16.3終於出來了,最大的變動莫過於生命週期去掉了以下三個componentWillMountcomponentWillReceivePropscomponentWillUpdate同時為了彌補失去上面三個週期的不足又加了兩個static getDerivedStateFromProp

玩具,React v16.7.0-alpha Hooks

ola tro 函數 小程序 之路 stat tst com onclick 周五看見React v16.7.0-alpha Hooks,今早起來看見圈裏已經刷屏了Hooks,正好周末,正好IG和G2的比賽還沒開始,研究下。。。 剛剛接觸react時候非常喜歡用函數式組

工業物聯網7 生命週期管理(3

7.3    實施部署 實施部署階段的工作就是,根據論證過的設計,開始搭建解決方案的基礎設施和運營團隊,獲取外部支援,最終產生一個可以執行的交付物。交付物根據方案的型別不同,可能是單項產品、應用系統或者

React學習元件生命週期、元件間資料傳遞

注:本篇文章僅供個人日後複習,所以沒什麼乾貨,只起類似“備忘錄”的作用。最近,在看《深入淺出React和Redux》,目前到第二章了,這是本章程式碼:(1)counter.jsimport React, { Component } from 'react'; import P

12、Cocos2dx 3.0遊戲開發找小三之3.0中的生命周期分析

ide () mil and 地理 splay ioe ase ima 重開發人員的勞動成果。轉載的時候請務必註明出處:http://blog.csdn.net/haomengzhu/article/details/27706303 生命周期分析 在前面文章中我

Maven生命週期外掛。

Maven的生命週期與外掛相互繫結,用以完成實際的構建任務。具體而言,是生命週期的階段與外掛的目標相互繫結,以完成某個具體的構建任務。例如專案編譯這一任務,他對應了default生命週期的compile這一階段,而maven-compiler-plugin這一外掛的compile目標能夠完成該任務。

react入門筆記七 (元件的生命週期)

生命週期分三個狀態 mounting(元件掛載階段) updating(元件更新) unmounting(元件移除) props與state         生命週期分四個階段 建立階

JVAWEB學習(3) — Serlvet的生命週期

Servlet的生命週期 什麼是Servlet的生命週期 Servlet容器如何建立Servlet物件,如何對該物件進行初始化處理,如何呼叫該物件的方法拉處理請求,以及如何銷燬該物件的整個過程。 Servlet的宣告週期分成哪幾個階段 1. 例項化 什麼是

3、Bean的生命週期

1、資源定位(@ComponentScan掃描) → Bean定義(將Bean定義儲存到BeanDefinition例項中) → 釋出Bean定義(IOC容器裝在Bean定義) → 例項化(建立Bean的例項物件) → 依賴注入(@Autowired注入資源) → setBeanName方法

vue生命週期react生命週期對比

一 vue的生命週期如下圖所示(很清晰)初始化、編譯、更新、銷燬   二 vue生命週期的栗子  注意觸發vue的created事件以後,this便指向vue例項,這點很重要 <!DOCTYPE html> <html> <head> <

【劉文彬】區塊鏈3.0擁抱EOS

原文連結:醒者呆的部落格園,https://www.cnblogs.com/Evsward/p/eos-intro.html EOS是當下最火的區塊鏈技術,被社會廣泛看好為下一代區塊鏈3.0。不同於以太坊的學習,EOS的主語言是C++,本文作為EOS研究的首篇文章,重點介紹EOS

工業物聯網7 生命週期管理(2)

7.2    設計論證 在明確了,或者說至少是階段性地明確了使用者需求之後,實施團隊就需要設計方案並論證其可行性。設計和論證的依據都是需求分析的結果。這個過程是一個迭代,因為經常在論證的過程中隨著對方案理解的加深而發現之前需求獲取和分析過程中的盲區與錯誤。設計論證的結果就是產

Vue2.0 探索之路——生命週期鉤子函式的一些理解

前言 在使用vue一個多禮拜後,感覺現在還停留在初級階段,雖然知道怎麼和後端做資料互動,但是對於mounted這個掛載還不是很清楚的。放大之,對vue的生命週期不甚瞭解。只知道簡單的使用,而不知道為什麼,這對後面的踩坑是相當不利的。 因為我們有時候會在幾個鉤子函式裡做一些

React Hooks (React v16.7.0-alpha)

什麼是Hooks “Hooks” 本意是”鉤子“的意思。在 React 裡,hooks 就是一系列特殊的函式,使函式元件 (functional component) 內部能夠”鉤住“ React 內部的 state 和 life-cycles。 為什麼使用Hooks 剛剛接觸react時候非常喜歡

通過實際部署應用程式來學習Web 3.0動手實踐(IPFS +以太坊)

“分散式網路”或“Web 3.0”現因其將給當今行業帶來的革命性變革已儼然成為流行語。但是我們中有多少人真正瞭解Web 3.0呢? 在本文中,我會對Web 3.0的顯著特點進行介紹。在獲得對Web 3.0的基本瞭解之後,我們將一起在IPFS上部署應用程式。該應用程式具有一份Solidit

spring原始碼分析spring生命週期

接著上一篇我們看看具體是哪裡的程式碼執行了。 1.初始化BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactory);--> PostProcessorRegistrationDelegate.