React Context 的基本用法


Context 提供了一個無需為每層組件手動添加 props,就能在組件樹間進行數據傳遞的方法。

1. 用法

React.createContext

const MyContext = React.createContext(defaultValue);

創建一個 Context 對象。當 React 渲染一個訂閱了這個 Context 對象的組件,這個組件會從組件樹中離自身最近的那個匹配的 Provider 中讀取到當前的 context 值。

只有當組件所處的樹中沒有匹配到 Provider 時,其 defaultValue 參數才會生效。這有助於在不使用 Provider 包裝組件的情況下對組件進行測試。注意:將 undefined 傳遞給 Provider 的 value 時,消費組件的 defaultValue 不會生效。

Context.Provider

<MyContext.Provider value={/* 某個值 */}>

每個 Context 對象都會返回一個 Provider React 組件,它允許消費組件訂閱 context 的變化。

Provider 接收一個 value 屬性,傳遞給消費組件。一個 Provider 可以和多個消費組件有對應關系。多個 Provider 也可以嵌套使用,里層的會覆蓋外層的數據。

Context.Consumer

<MyContext.Consumer>
  {value => /* 基於 context 值進行渲染*/}
</MyContext.Consumer>

這里,React 組件也可以訂閱到 context 變更。這能讓你在函數式組件中完成訂閱 context。

2. 實例應用

image

如圖,在父組件中定義兩個變量:fruit 和 count。子組件可以拿到父組件的fruit,子子組件可以拿到父組件的 fruit,並且可以改變count的值。

實現步驟如下:

2.1 新建文件 context.js

創建一個Context 對象,並導出Provider和Consumer容器。

import { createContext } from 'react'

export const { Provider, Consumer } = createContext()

2.2 新建父組件 index.js

import React, { Component } from 'react'
import { Provider } from './context' // 引入Provider
import Son from './Son' // 引入子組件

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {
      fruit: 'apple',
      count: 0,
    }
  }

  componentDidMount() {}

  getContext = () => {
    const { fruit, count } = this.state
    return {
      fruit,
      countUtil: {
        addCount: num => {
          this.setState({
            count: count + num,
          })
        },
        delCount: num => {
          this.setState({
            count: count - num,
          })
        },
      },
    }
  }

  render() {
    const { fruit, count } = this.state
    return (
      // Provider 容器, 其value接收一個getContext方法
      <Provider value={this.getContext()}>
        父組件 fruit = {fruit}, count = {count}
        <hr />
        <Son />
      </Provider>
    )
  }
}

export default Main

2.3 新建子組件 Son.js

import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer
import GrandSon from './GrandSon' // 引入子子組件

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    return (
      // Consumer 容器,可以拿到父組件傳遞下來的 fruit 屬性, 並可以展示對應的值
      <Consumer>
        {context => (
          <div>
            子組件 fruit={context.fruit}
            <hr />
            <GrandSon />
          </div>
        )}
      </Consumer>
    )
  }
}

export default Main

2.4 新建子子組件 GrandSon.js

import React, { Component } from 'react'
import { Consumer } from './context' // 引入Consumer

class Main extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }

  render() {
    return (
      // Consumer 容器,可以拿到父組件傳遞下來的 fruit 屬性, 以及 countUtil對象下的 addCount 和 delCount 方法
      <Consumer>
        {context => (
          <div>
            子子組件 fruit={context.fruit}
            <br />
            <button type="button" onClick={() => context.countUtil.addCount(2)}>
              加2
            </button>
            &nbsp;
            <button type="button" onClick={() => context.countUtil.delCount(3)}>
              減3
            </button>
            <hr />
          </div>
        )}
      </Consumer>
    )
  }
}

export default Main


免責聲明!

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



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