React 中 Context 的使用

ReactContext 的使用

context

Context 提供了一種方式,可以讓數據在組件樹中傳遞時沒必要一級一級的手動傳遞html

通常狀況下,數據在組件中,要一級一級的傳遞,單向數據流,好比Parent組件中的theme值,須要在Item組件中使用,就須要咱們從Parent中向下傳遞, 但當咱們有了Context後,咱們就不須要一級一級傳遞了react

Parent(theme=red)
    List(theme=red)
        Item(theme=red)
        
ThemeContext.Provider value={'red'}
    List
        ThemeContext.Customer  (theme) => { theme }
複製代碼

具體如何使用呢,看下面例子git

import React, { createContext } from 'react';

// 建立Context的惟一方法
const ThemeContext = createContext()



class App extends React.Component {
  render () {
    return (
      // 使用 Context.Provider 包裹後續組件,value 指定值 
      <ThemeContext.Provider value={'red'}>
        <Middle></Middle>
      </ThemeContext.Provider>
    )
  }
}

class Bottom extends React.Component {
  render () {
    return (
      // Context.Consumer Consumer消費者使用Context得值
      // 但子組件不能是其餘組件,必須渲染一個函數,函數的參數就是Context得值
      <ThemeContext.Consumer>
        {
          theme => <h1>ThemeContext 的 值爲 {theme}</h1>
        }
      </ThemeContext.Consumer>
    )
  }
}


class Middle extends React.Component {
  render () {
    return <Bottom></Bottom>
  }
}

export default App;


複製代碼

當 Provider 提供的值更改時,Consumer 必須從新渲染github

import React, { createContext } from 'react';

// 建立Context的惟一方法
const ThemeContext = createContext()



class App extends React.Component {
  state = {
    theme: 'red'
  }
  render () {
    const { theme } = this.state
    return (
      // 使用 Context.Provider 包裹後續組件,value 指定值 
      <ThemeContext.Provider value={theme}>
        {/* 當Context的Provider值更改時,Consumer 的值必須從新渲染 */}
        <button onClick={() => {
            this.setState({ theme: 'yellow'})}}
        >按鈕</button>
        <Middle></Middle>
      </ThemeContext.Provider>
    )
  }
}

class Bottom extends React.Component {
  render () {
    return (
      // Context.Consumer Consumer消費者使用Context得值
      // 但子組件不能是其餘組件,必須渲染一個函數,函數的參數就是Context得值
      <ThemeContext.Consumer>
        {
          theme => <h1>ThemeContext 的 值爲 {theme}</h1>
        }
      </ThemeContext.Consumer>
    )
  }
}


class Middle extends React.Component {
  render () {
    return <Bottom></Bottom>
  }
}

export default App;

複製代碼

當出現多個Context的時候,應該如何使用呢web

import React, { createContext } from 'react';

// 建立Context的惟一方法
const ThemeContext = createContext()
const SizeContext = createContext()


class App extends React.Component {
  state = {
    theme: 'red',
    size: 'small'
  }
  render () {
    const { theme, size } = this.state
    return (
      // 使用 Context.Provider 包裹後續組件,value 指定值 
      <ThemeContext.Provider value={theme}>
        {/* 當出現多個Context的時候,只須要將Context.Provider 嵌套便可 */}
        <SizeContext.Provider value={size}>
          {/* 當Context的Provider值更改時,Consumer 的值必須從新渲染 */}
          <button onClick={
            () => {
                this.setState({ theme: 'yellow', size: 'big'})
            }
          }>按鈕</button>
          <Middle></Middle>
        </SizeContext.Provider>
      </ThemeContext.Provider>
    )
  }
}

class Bottom extends React.Component {
  render () {
    return (
      // Context.Consumer Consumer消費者使用Context得值
      // 但子組件不能是其餘組件,必須渲染一個函數,函數的參數就是Context得值
      // 當出現 多個Consumer的時候,進行嵌套,每一個Consumer
      // 的子組件必須是一個函數,便可
      <ThemeContext.Consumer>
        {
          theme => (
            <SizeContext.Consumer>
              {
                size => (
                    <h1>
                        ThemeContext 的 值爲 {theme}; 
                        SizeContext 的值爲 {size}
                    </h1>
                )
              }
            </SizeContext.Consumer>
          )
        }
      </ThemeContext.Consumer>
    )
  }
}


class Middle extends React.Component {
  render () {
    return <Bottom></Bottom>
  }
}

export default App;
複製代碼

假如、Consumer 向上找不到 Provider 的時候,怎麼辦,react 並不會報錯,只不過取不到值而已、這個時候建立 Context 的時候 createContext 能夠傳入默認值,當找不到 Provider 的時候,就會顯示默認值性能優化

注意:context相似於全局變量作法,會讓組件失去獨立性、複用起來更困難,不能濫用、但自己它必定有適合使用的場景,具體看狀況使用bash

contextType

contextType 能夠簡化 context 的使用,不使用 consumer 也能夠共享變量ide

具體看下面例子函數

import React, { createContext } from 'react';

// 建立Context的惟一方法
const ThemeContext = createContext()
const SizeContext = createContext()


class App extends React.Component {
  state = {
    theme: 'red',
    size: 'small'
  }
  render () {
    const { theme, size } = this.state
    return (
      // 使用 Context.Provider 包裹後續組件,value 指定值 
      <ThemeContext.Provider value={theme}>
        {/* 當出現多個Context的時候,只須要將Context.Provider 嵌套便可 */}
        <SizeContext.Provider value={size}>
          {/* 當Context的Provider值更改時,Consumer 的值必須從新渲染 */}
          <button onClick={() => {this.setState({ theme: 'yellow', size: 'big'})}}>按鈕</button>
          <Middle></Middle>
        </SizeContext.Provider>
      </ThemeContext.Provider>
    )
  }
}

class Bottom extends React.Component {
  // 申明靜態變量、contextType 將 context 直接賦值於 contextType
  static contextType = ThemeContext
  
  render () {
    // 在 render 函數中 能夠直接 訪問 this.context 獲取共享變量、這樣就能夠不使用 consumer
    const theme = this.context
    return (
      // Context.Consumer Consumer消費者使用Context得值
      // 但子組件不能是其餘組件,必須渲染一個函數,函數的參數就是Context得值
      // 當出現 多個Consumer的時候,進行嵌套,每一個Consumer 的子組件必須是一個函數,便可
      <div>
        <h1>ThemeContext 的 值爲 {theme} </h1>
      </div>
    )
  }
}

class Middle extends React.Component {
  render () {
    return <Bottom></Bottom>
  }
}

export default App;
複製代碼

注意:

  • contextType 只能在類組件中使用
  • 一個組件若是有多個 consumer , contextType 只對其中一個有效,因此說,contextType 只能有一個

參考:

  1. 官方文檔

代碼地址

  1. GitHub

react 其餘文檔

  1. React 中 lazy, Suspense 以及錯誤邊界(Error Boundaries)的使用
  2. React 中性能優化、 memo、 PureComponent、shouldComponentUpdate 的使用

若是對你有幫助,點個贊吧性能

相關文章
相關標籤/搜索