React的Context的使用方法簡介
阿新 • • 發佈:2019-07-21
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
&n