React的Context的使用方法簡介

context html

定義: Context提供了一種方式,可以讓數據在組件樹中傳遞,而沒必要一級一級手動傳遞。react

API : createContext(defaultValue?)。ide

使用方法:函數

首先要引入createContextthis

 

import React, { Component, createContext } from 'react';

 

 而後建立一個Context spa

const BatteryContext = createContext();

 

而後用BatteryContext.Provider包裹組件而且傳遞屬性值。code

<BatteryContext.Provider value={60}>
     <Middle />  //子組件
</BatteryContext.Provider>

 

 爲了方便看出效果,將定義一個子組件和一個孫組件。而後不經過子組件,孫組件直接取值htm

import React, { Component, createContext } from 'react'; const BatteryContext = createContext(); //聲明一個孫組件
class Leaf extends Component { render() { return ( ) } } //聲明一個子組件
class Middle extends Component { render() { return <Leaf /> 
 } } class App extends Component { render(){ return ( <BatteryContext.Provider value={60}>
        <Middle />
      </BatteryContext.Provider>
 ); } } export default App;

 

孫組件須要BatteryContext.Consumer來接收值,Consumer裏面不能直接渲染其餘組件,而是要聲明一個函數。函數的參數就是context的值。blog

class Leaf extends Component { render() { return ( <BatteryContext.Consumer> { battery => <h1>Battery : {battery}</h1>
 } </BatteryContext.Consumer>
 ) } }

 

 效果圖;get

 

這樣沒經過Middle組件來傳遞值,可是Leaf組件能經過context來得到屬性。這就是context的基本用法。

 

context不但能跨層級來傳遞屬性值,還能在屬性值發生變化的時候重渲染Consumer下面的元素,舉個例子:
 
在state中定義battery並賦值
state = { battery: 60 }

 

而後作一個按鈕,每次點擊的時候都要battery減一。  代碼:
render() { const { battery } = this.state; return ( <BatteryContext.Provider value={battery}>
        <button type="button" onClick={() => this.setState({ battery: battery - 1 })} > 減減 </button>
        <Middle />
      </BatteryContext.Provider>
 ); }

 

所有代碼:
import React, { Component, createContext } from 'react'; const BatteryContext = createContext(); //聲明一個孫組件
class Leaf extends Component { render() { return ( <BatteryContext.Consumer> { battery => <h1>Battery : {battery}</h1>
 } </BatteryContext.Consumer>
 ) } } //聲明一個子組件
class Middle extends Component { render() { return <Leaf />
 } } class App extends Component { state = { battery: 60 } render() { const { battery } = this.state; return ( <BatteryContext.Provider value={battery}>
        <button type="button" onClick={() => this.setState({ battery: battery - 1 })} > 減減 </button>
        <Middle />
      </BatteryContext.Provider>
 ); } } export default App;

 

 效果圖: 

 

這樣每次點擊都會使battery得數值發生變化,從而重渲染Consumer下面的元素。

 

若是有多個Context該怎麼作呢?咱們在建立一個 Context
const OnLineContext = createContext();

 

若是有多個context變量的話,只須要把Privider嵌套進來便可,順序不重要。接下來聲明online的Provider了。
class App extends Component { state = { battery: 60, online: false } render() { const { battery, online } = this.state; return ( <BatteryContext.Provider value={battery}>
        <OnLineContext.Provider value={online} >
          <button type="button" onClick={() => this.setState({ battery: battery - 1 })} > 減減 </button>
          <button type="button" onClick={() => this.setState({ online: !online })} > Switch </button>
          <Middle />
        </OnLineContext.Provider>
      </BatteryContext.Provider>
 ); }

 

與Provider相似。Consumer也須要嵌套,順序不重要。只要Consumer須要聲明函數,因此要注意語法。
class Leaf extends Component { render() { return ( <BatteryContext.Consumer> { battery => ( <OnLineContext.Consumer> { online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
 } </OnLineContext.Consumer>
 ) } </BatteryContext.Consumer>
 ) } }

 

 所有代碼:

import React, { Component, createContext } from 'react'; const BatteryContext = createContext(); const OnLineContext = createContext(); //聲明一個孫組件
class Leaf extends Component { render() { return ( //與Provider相似。Consumer也須要嵌套,順序不重要。只要Consumer須要聲明函數,因此要注意語法。
      <BatteryContext.Consumer> { battery => ( <OnLineContext.Consumer> { online => <h1>Battery : {battery} , Online : {online.toString()}</h1>
 } </OnLineContext.Consumer>
 ) } </BatteryContext.Consumer>
 ) } } //聲明一個子組件
class Middle extends Component { render() { return <Leaf />
 } } class App extends Component { state = { battery: 60, online: false } render() { const { battery, online } = this.state; //接下來聲明online的Provider了。若是有多個context變量的話,只須要把Privider嵌套進來便可,順序不重要。
    return ( <BatteryContext.Provider value={battery}>
        <OnLineContext.Provider value={online} >
          <button type="button" onClick={() => this.setState({ battery: battery - 1 })} > 減減 </button>
          <button type="button" onClick={() => this.setState({ online: !online })} > Switch </button>
          <Middle />
        </OnLineContext.Provider>
      </BatteryContext.Provider>
 ); } } export default App;

 

效果圖:

 

 

還有一個問題 , 若是Consumer向上找不到對應的Provider怎麼辦?
 
其實即便找不到也不會報錯,而是顯示爲空。那怎麼設置默認值呢?
 
那上面的demo舉例 ,剛纔咱們設置的battery爲60。若是Consumer向上找不到BatteryContext.Provider的值,咱們能夠這樣設置默認值:
const BatteryContext = createContext(30);
這樣BatteryContext.Consumer向上找不到值,就會取默認值30。

 

context不單單只是能夠傳數值,也能夠傳函數。你們能夠試試看。
最後再提示一下你們,不要濫用context,否則會影響組件的獨立性。 若是一個組件中只使用一個Context的話,就可使用contextType代替Consumer。詳見http://www.javashuo.com/article/p-rfricsbm-mn.html
相關文章
相關標籤/搜索