美文网首页
React - 上下文处理组件跨层级通信

React - 上下文处理组件跨层级通信

作者: 闪电西兰花 | 来源:发表于2020-08-21 16:16 被阅读0次
  • 上下文处理组件跨层级通信:
    1. 使用上下文中的 Consumer
    2. 使用 Hook api useContext
    3. class 类组件中,将创建的上下文赋值给一个静态属性 contextType
  • 上下文处理的组件跨层级通信主要是由最外层组件向内层组件传递数据,像Vue中的 inject,不需要再层层传递props
  • 先初始化一个 child 组件,然后去实现跨组件层级和Child 通信
// src/components/ContextTest.js
import React from 'react';

function Child () {
  return (
    <div>Child</div>
  )
}

export default function ContextTest () {
  return (
    <div>
      <Child></Child>
    </div>
  )
}
  • 使用上下文之前要先创建上下文,然后从上下文中解构出 Provider,再用 Provider 将接收数据的组件包裹起来,然后通过 Providervalue 属性就可以实现跨组件层级传递数据了
// src/components/ContextTest.js
import React from 'react';

// 创建上下文
// 这个功能概念可理解为vue中的provide和inject
const MyContext = React.createContext()
const {Provider} = MyContext

function Child () {
  return (
    <div>Child</div>
  )
}

export default function ContextTest () {
  return (
    <div>
      {/* 将Child组件用Provider包裹起来,通过Provider的value属性就可以传值了 */}
      <Provider value={{name: 'asher'}}>
        <Child></Child>
      </Provider>
    </div>
  )
}
  • 实现了跨组件传值,那就要再继续解决跨组件接收值,有一种方式是使用上下文中的 Consumer,所有需要接收数据的组件用 Consumer 包裹起来,然后 Consumer 能拿到 Provider 传递出来的值, Consumer 再通过函数形式传递出去,ConsumerProvider 之间可以有很多层组件间隔
// src/components/ContextTest.js
import React from 'react';

// 创建上下文
// 这个功能概念可理解为vue中的provide和inject
const MyContext = React.createContext()
// 解构出Provider、Consumer
const {Provider, Consumer} = MyContext

// Child组件中通过props获取 
function Child (props) {
  return (
    <div>Child: {props.name}</div>
  )
}

export default function ContextTest () {
  return (
    <div>
      {/* 将Child组件用Provider包裹起来,通过Provider的value属性就可以传值了 */}
      <Provider value={{name: 'asher'}}>
        {/* 需要接收值的组件要被包裹在Consumer内 */}
         {/* Consumer内部执行一个方法,拿到传递的值传给Child,有点类似组件复合 */}
        <Consumer>
          {val => <Child {...val}></Child>}
        </Consumer>
      </Provider>
    </div>
  )
}
  • 接收值的另一种方式是使用 Hook,使用 Hook api useContext,我们改写下上面的代码让代码看起来清晰一点,不同的接收值方法分别用不同的组件来展示,同时引入下 useContext
// src/components/ContextTest.js
import React, {useContext} from 'react';

const MyContext = React.createContext()
const {Provider, Consumer} = MyContext

// 跨组件通信方法1:利用<consumer></consumer>组件
function Child1 (props) {
  return ( 
    <div>child1: {props.name}</div>
  )
}

// 跨组件通信2:使用hook
function Child2 () {
  // 把创建的上下文传递给useContext
  // 直接从上下文中获取属性
  const ctx = useContext(MyContext)
  return (
    <div>child2: {ctx.name}</div>
  )
}

export default function ContextTest () {
  return (
    <div>
      <Provider value={{name: 'asher'}}>
 
        {/* 跨组件通信方法1 */}
        <Consumer>
          {val => <Child1 {...val}></Child1>}
        </Consumer>

        {/* 跨组件通信方法2 */}
        <Child2></Child2>

      </Provider>
    </div>
  )
}
  • 接收值的第3种方式是针对于 class 类组件的,使用类组件中的静态属性 contextType
// src/components/ContextTest.js
import React, {useContext} from 'react';

const MyContext = React.createContext()
const {Provider, Consumer} = MyContext

// 跨组件通信方法1:利用<consumer></consumer>组件
function Child1 (props) {
  return ( 
    <div>child1: {props.name}</div>
  )
}

// 跨组件通信2:使用hook
function Child2 () {
  // 把创建的上下文传递给useContext
  // 直接从上下文中获取属性
  const ctx = useContext(MyContext)
  return (
    <div>child2: {ctx.name}</div>
  )
}

// 跨组件通信3:class指定静态contextType
class Child3 extends React.Component {
  // 声明一个静态属性
  // 通过固定变量名this.context获取
  static contextType = MyContext
  render () {
    return (
      <div>Child3: {this.context.name}</div>
    )
  }
}

export default function ContextTest () {
  return (
    <div>
      <Provider value={{name: 'asher'}}>
 
        {/* 跨组件通信方法1 */}
        <Consumer>
          {val => <Child1 {...val}></Child1>}
        </Consumer>

        {/* 跨组件通信方法2 */}
        <Child2></Child2>

        {/* 跨组件通信方法3 */}
        <Child3></Child3>

      </Provider>
    </div>
  )
}

相关文章

网友评论

      本文标题:React - 上下文处理组件跨层级通信

      本文链接:https://www.haomeiwen.com/subject/xqrkrktx.html