React Context跨组件传递属性

76 阅读2分钟

React的数据传递方式是:

  1. props:只能父传子
  2. redux:数据传递不多的时候使用会有点重
  3. 数据共享:context 上下文

今天来介绍第三种数据共享写法:

在v16.3之前的context只是官方的实验性API,其实官方是不推荐开发者使用的,但是架不住很多框架依旧在使用它;所以官方在v16.3发布的新的context API,新的API会更加的易用,本文也是以v16.3为准。

react@16.x 版本之前:

  1. 静态属性 childContextType:声明所需要的数据结构
  2. PropTypes (prop-types库): 来检查声明类型
  3. getChildContext():返回需要提供的context值

Provide 封装代码:

import PropTypes from 'prop-types'
class Provide extends React.Component{
    // 1.声明:检查context共享值的类型
    static childContextType = {
      // 2.用PropTypes来声明context类型
       store: PropTypes.object.isRequired
    }
    constructor(props){
     // 获取传进来的参数 并赋值给store变量
        super(props);
        this.store = {...props}
    }
    // 3.返回共享值
    getChildContext(){
      return {
         store: this.store
      }
    }
    render(){
        return (
            <div>
                {this.props.children}
            </div>
        )
    }

}

父组件(提供者)代码 :通过包裹使所有子组件共享数据

import Provide from './provide';
import CustomChild from './CustomChild';

class CustomParent extends React.component{
    render(){
        return (
         // 使用provide共享信息,所有北provide组件包括的均可以获取到共享的data信息
          <Provide data={{name:"xx",sex:""}}>
              // 子组件中会有name,sex的信息
              <CustomChild/>
              <CustomChild1/>
          </Provide>
        )
    }
}

子组件(消费者)代码:通过this.context.xx 获取

class CustomChild extends React.component{
    render(){
        return (
          <div>
              共享信息:{this.context.store.name}
          </div>
        )
    
    }

}


备注:
propTypes校验: 防止缺陷并规划组件使用的数据种类
prop-types库: 只在开发模式中进行类型评估,运行在生产环境不会耗费额外的精力 react@16之前是核心react库的一部分, 现在作为prop-types包单独存在

React@16 以后的版本:createContext

  • React提供了一个createContext的方法,
    • 该方法返回一个包含了
      • Provider对象:提供者
      • Consumer对象:消费者

父组件:

    import {createContext} from "react";
    const defaultValue={
      color: "green",
      fontSize: "20px"
    }
    
    export const PrentContext = createContext(defaultValue);
   render() {
     return (
     <div className="App">
        <PrentContext.rovider value={this.state}>
            <Parent/>
         </PrentContext.rovider>
     </div>
    );
    }

HOOK: useContext

Hook 是 React 16.8.0 版本增加的新特性,可以在函数组件中使用 state以及其他的 React 特性。只能在函数组件中使用

父组件:创建+包裹

export const ContactContext = createContext({});

function parent(){
    <ContactContext.Provider value={{ itemData: res }} >                     
        <ShowName />
        <ShowSex/>
    </ContactContext.Provider>
}

子组件接收数据:useContext(父定义的context)

const ShowName = () => {
    const {itemData:{name}} = useContext(ContactContext);
    return (
          <span className='name'>{name}</span>
    )
}

接受最近一层 provider中的value属性