React 16.3(.0-alpha)新特性

React 16.3-alpha已經發布。此次發佈都有哪些新特性呢,咱們來一塊兒看看。react

新的Context API

Context API老是很讓人迷惑。這個API是官方的,可是官方又不但願開發者們使用這個API,說是這個API會在之後發生改變。如今就是那個改變的時刻。新的API已經被merge了。並且它看起來更加的「用戶友好」了。尤爲是你不得不使用redux、mobx的時候,能夠選擇新的Context API實現更加簡單的狀態管理。git

新的API用起來很是的簡單:React.createContext(),這樣就建立了兩個組件:github

import {createContext} from 'react';

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

調用createContext方法會返回兩個對象,一個是Provider,一個是Consumerredux

那個Provider是一個特殊的組件。它能夠用來給子樹裏的組件提供數據。一個例子:異步

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

上例展現瞭如何傳遞「theme」 context的。固然這些值能夠是動態的(好比,基於this.state)。ide

下一步就是使用Consumer學習

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

若是在render Consumer的時候沒有嵌套在一個Provider裏面。那麼就會使用createContext方法調用的時候設置的默認值。ui

注意:this

  • Consumer必須能夠訪問到同一個Context組件。若是你要建立一個新的context,用的是一樣的入參,那麼這個新建的context的數據是不可訪問的。所以,能夠把Context當作一個組件,它能夠建立一次,而後能夠export,能夠import。
  • 這個新的語法用了function as child模式(有時也叫作render prop模式)。若是不是很熟悉這個模式,那麼推薦你看一下這些文章
  • 新的API再也不要求你聲明contextProps了。

Context傳遞的數據和Context.Provider組件的value屬性是同樣的。對Provider數據的修改會引發全部的消費者(consumer)重繪。code

新的聲明週期方法

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

這一改變主要是爲了強制推行最佳實踐。你能夠看看這篇文章來了解一下爲何這些生命週期方法會變得很詭異。這些最佳模式在React 16的異步繪製模式(Async Mode)下顯得很是重要。

要被廢棄的方法:

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

不過這些並不會馬上發生,他們能夠用到React 16.4。在React 17裏將被完全移除。若是你開啓了StrictMode或者AsyncMode,能夠經過這樣的方式來使用,可是會收到警告:

  • UNSAFE_componentWillMount
  • UNSAFE_componentWillReceiveProps
  • 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: 'black', color: 'white'}}>
          <Header />
          <Main />
          <Footer />
        </Context.Provider>
      </StrictMode>
    );
  }
}

若是一個在StricMode子樹裏的組件使用了componentWillMount方法,那麼你會看到一個報錯消息。

AsyncMode

異步模式在React.unsafe_AsyncMode下。使用AsncMode也會打開StrictMode模式下的警告。

若是你想學習更多異步模式的內容,你能夠在下面的地方看到更多的文章和示例:

新版React Developer Tools

這個做者發文的時候竟然是Firefox支持了最新版的React。而Chrome還木有。。。

原文地址:https://medium.com/@baphemot/...

相關文章
相關標籤/搜索