React的Context的使用方法簡介


context

定義: Context提供了一種方式,能夠讓數據在組件樹中傳遞,而不必一級一級手動傳遞。

API : createContext(defaultValue?)。

使用方法:

首先要引入createContext

 

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

 

 然后創建一個Context 

const BatteryContext = createContext();

 

然后用BatteryContext.Provider包裹組件並且傳遞屬性值。

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

 

 為了方便看出效果,將定義一個子組件和一個孫組件。然后不通過子組件,孫組件直接取值

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的值。

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

 

 效果圖;

 

這樣沒通過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。詳見https://www.cnblogs.com/littleSpill/p/11221817.html
 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM