Skip to content
{}

基础知识 - 跨组件通信

context方案

通过包裹的方式 在provider(供应商)value属性上面定义数据|方法 ,Consumer(消费者) 内部调用回调函数 利用回调的形参 来获取数据|方法

  • createContext()方法 : const ContextDom = React.createContext()

可以创建一个跨组件实例对象

  • Provider属性: <ContextDom.Provider value={ { 数据|方法 } }> <div>父组件根元素</div> </ContextDom.Provider>

用来包裹父组件根元素标签 标签上有个value属性 可以定义全局数据 子组件可以用里面定义的数据和方法

import React, { Component } from "react";
const ContextDom = React.createContext();
class App extends Component {
  state = {
    content: "", //需要传递的数据
  };
  render() {
    return (
      // 用实例对象的Provider属性 包裹根元素 标签上有一个value属性用来定义数据
      // 子组件可以访问到value传递过去的数据
        <ContextDom.Provider
            value={{
            title: "前端猛男",
            content: this.state.content, //动态绑定传递的值
            ChangeContent: (content) => {
                // 子组件调用此方法修改传递过来的数据 来更新组件
                this.setState({
                    content: content,
                });
            },
          }}
        >
            <div>
                App
            </div>
        </ContextDom.Provider>
        );
    }
}
  • Consumer属性: <ContextDom.Consumer>{ (Context)=> 子组件根元素标签 }</ContextDom.Consumer>

用来包裹需要接收的子元素的根标签 内部需要一个回调函数 函数的返回值是子组件的根标签 回调函数的形参 就是包裹父组件Provider标签上面value属性里面定义的数据|方法 可以调用上面定义的方法 修改父组件定义与value属性绑定的数据 从而让父组件刷新 子组件也相应的跟着变化

import React, { Component } from "react";
const ContextDom = React.createContext();
const Childen1 = (props) => {
  const { name, content } = props;
  return (
    <!-- 包裹 -->
    <ContextDom.Consumer>
      {(Context) => {
        console.log(Context);
        return (
          <div
            onClick={() => {
              Context.ChangeContent(content);
            }}
          >
            {name}
          </div>
        );
      }}
    </ContextDom.Consumer>
  );
};
class Childen2 extends Component {
  render() {
    return (
    <!-- 包裹 -->
      <ContextDom.Consumer>
        {(Context) => {
          console.log(Context);
          return <div>{Context.content}</div>;
        }}
      </ContextDom.Consumer>
    );
  }
}

综合小Demo

import React, { Component } from "react";
import ReactDom from 'react-dom';
// 创建context对象
const ContextDom = React.createContext();

const Childen1 = (props) => {
  const { name, content } = props;
  return (
    // 用实例对象的Consumer属性 包裹需要通信的子组件的跟元素 他内部是个回调函数
    // 内部需要返回我们的根元素标签 形参就是传过来的数据
    <ContextDom.Consumer>
      {
        (Context) => {
            console.log(Context);
            return (
                // 调用形参上面 根元素provider定义的方法 将数据传递过去进行更改
                <div onClick={() => {
                        Context.ChangeContent(content);
                    }}>
                    {name}
                </div>
            );
        }
      }
    </ContextDom.Consumer>
  );
};
class Childen2 extends Component {
  render() {
    return (
      // 用实例对象的Consumer属性 包裹需要通信的子组件的跟元素 他内部是个回调函数
      // 内部需要返回我们的根元素标签 形参就是传过来的数据
      <ContextDom.Consumer>
        { 
            (Context) => {
                console.log(Context);
                // 调用形参上面 父组件Provider定义的值
                return <div>{Context.content}</div>;
            } 
        }
      </ContextDom.Consumer>
    );
  }
}

class App extends Component {
  state = {
    list: [
      { id: 1, name: "前端猛男1", content: "我是前端猛男1" },
      { id: 2, name: "前端猛男2", content: "我是前端猛男2" },
      { id: 3, name: "前端猛男3", content: "我是前端猛男3" },
      { id: 4, name: "前端猛男4", content: "我是前端猛男4" },
    ],
    content: "", //需要传递的数据
  };
  render() {
    return (
      // 用实例对象的Provider属性 包裹根元素 标签上有一个value属性用来定义数据
      // 子组件可以访问到value传递过去的数据
      <ContextDom.Provider value={ {
          title: "前端猛男",
          content: this.state.content, //动态绑定传递的值
          ChangeContent: (content) => {
            // 子组件调用此方法修改传递过来的数据 来更新组件
            this.setState({
              content: content,
            });
          },
        } }
      >
         <!-- 根源素标签 -->
            <div>
                {this.state.list.map((item) => {
                    return <Childen1 key={item.id} {...item}></Childen1>;
                })}

                <Childen2></Childen2>
            </div>
      </ContextDom.Provider>
    );
  }
}
ReactDom.render(<App/>,ducoment.getElementById('root'))

好好加油吧,少年!