首頁  >  文章  >  web前端  >  React 16.3新特性分析

React 16.3新特性分析

小云云
小云云原創
2018-02-09 15:36:454303瀏覽

Context API總是很讓人迷惑。這個API是官方的,但是官方又不希望開發者使用這個API,說是這個API會在以後改變。現在就是那個改變的時刻。新的API已經被merge了。而且它看起來更加的「用戶友好」了。尤其是你必須使用redux、mobx的時候,可以選擇新的Context API實作更簡單的狀態管理。

新的API用起來非常的簡單:React.createContext(),這樣就建立了兩個元件:

import {createContext} from 'react';

const ThemeContext = createContext({
  background: 'yellow',
  color: 'white'
});

呼叫createContext方法會傳回兩個對象,一個是Provider,一個是Consumer

那個Provider是一個特殊的元件。它可以用來給子樹裡的元件提供資料。一個例子:

class Application extends React.Component {
  render() {
    <ThemeContext.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
      <Header />
      <Main />
      <Footer />
    </ThemeContext.Provider>
  }
}

上例展示如何傳遞「theme」 context的。當然這些值可以是動態的(例如,基於this.state)。

下一步就是使用Consumer

const Header = () => {
  <ThemeContext.Consumer>
    {(context) => {
      return (
        <p style={{background: context.background, color: context.color}}>
          Welcome!
        </p>
      );
    }}
  </ThemeContext.Consumer>
}

如果在render Consumer的時候沒有嵌套在一個Provider裡面。那麼就會使用createContext方法呼叫的時候設定的預設值。

注意:

  • Consumer必須可以存取到同一個Context#元件。如果你要建立一個新的context,用的是同樣的入參,那麼這個新建的context的資料是無法存取的。因此,可以把Context當做一個元件,它可以創建一次,然後可以export,可以import。

  • 這個新的語法用了function as child模式(有時也叫render prop模式)。如果不是很熟悉這個模式,那麼推薦你來看這些文章。

  • 新的API不再要求你宣告contextProps了。

Context傳遞的資料和Context.Provider元件的value屬性是一樣的。對Provider資料的修改會造成所有的消費者(consumer)重繪。

新的宣告週期方法

參考這個RFC。新的聲明週期方法會被引入,而舊的會被廢棄。

這項改變主要是為了強制推行最佳實踐。你可以看看這篇文章來了解為什麼這些生命週期方法會變得很詭異。這些最佳模式在React 16的非同步繪圖模式(Async Mode)下顯得非常重要。

要被廢棄的方法:

  • componentWillMount--使用componentDidMount

  • #componentWillUpdate--使用componentDidUpdate代替

  • componentWillReceiveProps--使用一個新的方法:static getDerivedStateFromProps來代替。

不過這些並不會立刻發生,他們可以用到React 16.4。在React 17裡將被徹底移除。如果你開啟了StrictModeAsyncMode,可以用這樣的方式來使用,但會收到警告:

  • UNSAFE_componentWillMount

  • UNSAFE_componentWillReceiveProps

  • UNSAFE_componentWillUpdate

#UNSAFE_componentWillUpdate

#UNSAFE_componentWillUpdate

static getDerivedStateFromProps

componentWillReceiveProps

我們需要其他的方式根據props的變動更新state。社群決定引入一個新的static方法來處理這個問題。 什麼是靜態方法?一個靜態方法就是存在於類別內,而不是類別的實例內的方法。靜態方法存取不到this,並且在聲明的時候有

static

關鍵字在前面修飾。 但是,問題來了。既然這個方法沒有辦法存取

this

,那麼如何呼叫

this.setState

呢?答案就是,不呼叫。這個方法直接傳回需要更新的state的數據,或傳回null,如果沒有什麼需要更新的話。

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.currentRow === prevState.lastRow) {
    return null;
  }

  return {
    lastRow: nextProps.currentRow,
    isCrollingDown: nextProps.curentRow > prevState.lastRow
  }
}

呼叫這個方法和之前呼叫this.setState的效果是一樣的。只會修改這些傳回的值,如果是null的話則不修改state。 state的其他值都會保留。 值得注意的事

你要定義初始state的值。無論是在constructor裡,或是類別屬性。否則會報警告。 這個方法

getDerivedStateFromProps()

會在第一次掛載和重繪的時候都會呼叫到,因此你基本上不用在constructor裡根據傳入的props來setState

如果定義了getDerivedStateFromProps後,又定義了

componentWillReceiveProps###。那麼,只有前者會被調用,並且你會收到一個警告。 ######一般你會使用一個回呼來確保某些程式碼實在state更新之後才被呼叫的。那麼,請把這些程式碼都移到###componentDidUpdate###裡。 ######如果你不喜歡使用###static###關鍵字,那你可以這樣:###
ComponentName.getDerivedStateFromProps = (nextProps, prevState) => {
  // Your code here
}

Static Mode

严格模式是一个新的方式来确保你的代码是按照最佳实践开发的。它实际是一个在React.StrictMode下的组件。它可以用在你的组件树的任何一部分上。

import {StrictMode} from 'react'

class Application extends React.Component {
  render() {
    return (
      <StrictMode>
        <Context.Provider value={{background: &#39;black&#39;, color: &#39;white&#39;}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}

如果一个在StricMode子树里的组件使用了componentWillMount方法,那么你会看到一个报错消息。

AsyncMode

异步模式在React.unsafe_AsyncMode下。使用AsncMode也会打开StrictMode模式下的警告。

相关推荐:

React 16.3之Context API详解


以上是React 16.3新特性分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn