【从0搭建react后台管理】8.react组件通信的方式

【项目地址】
https://gitee.com/shangqiao1996/member-points-mgmt


一、 父子组件(类组件和函数组件中都可)
  1. 父传子

    // 父组件
    import React, { Component } from "react";
    import Child from "./Child";
    export default class Parent extends Component {
      constructor(props) {
        super(props);
        this.state = {
          msg: "我是父组件的信息",
        };
      }
      render() {
        return (
          <div>
            // 父组件直接通过属性传递给子组件
            <Child msg={this.state.msg}></Child>
          </div>
        );
      }
    }
    // 子组件
     import React, { Component } from "react";
    // 子组件
    export default class Child extends Component {
      render() {
        // 子组件通过props接收父组件传递的值
        console.log(this.props);
        return (
          <div>
            // 子组件使用
            <p>{this.props.msg}</p>
          </div>
        );
      }
    }
    
  2. 子传父

    // 父组件
    class Parent extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          parentMsg: "",
        };
      }
      // 提供回调函数 接收子组件数据
      getChidMsg = (msg) => {
        console.log("子组件的数据", msg);
        this.setState({
          parentMsg: msg,
        });
      };
      render() {
        return (
          <div>
            父组件:{this.state.parentMsg}
            <br />
            子组件: <Child getMsg={this.getChidMsg}></Child>
          </div>
        );
      }
    }
    // 子组件
    class Child extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          msg: "子组件的值",
        };
      }
    
      // 子组件调用父组件中传递的回调函数
      handClick = () => {
        this.props.getMsc(this.state.msg);
      };
      render() {
        return (
          <div>
            <button onClick={this.handClick}> 点击我 </button>
          </div>
        );
      }
    }
    
二、 跨组件

如果目的子组件在组件嵌套的深层,直接用 props 传值是不实际的。

  1. context(组件树中从上到下,父到子)
    redux 的原理就是用 context 进行数据传输。
// 使用context实现跨组件通信
import React, { createContext } from "react";
// 1. 创建Context对象
const Context = createContext();

function A() {
  return (
    <div>
      <B></B>
      <Context.Consumer>{(value) => <span>{value}</span>}</Context.Consumer>
    </div>
  );
}
function B() {
  // 3. 通过Comsumer获取数据
  return (
    <div>
      <Context.Consumer>{(value) => <span>{value}</span>}</Context.Consumer>
    </div>
  );
  // 4. react16.8版本之后增加了hooks,可以使用hooks中的useContext来获取消费者
  import { useContext } from "react";
  const { message } = useContext(Context);
  // 直接这样定义就可以拿到consumer的值,省去了之前要定义在Consumer中才能使用。
}

class App extends React.Component {
  state = {
    message: "要传递的消息",
  };
  render() {
    return (
      // 2. 使用provider包裹根组件
      <Provider value={this.state.message}>
        <div>
          <A></A>
        </div>
      </Provider>
    );
  }
}
  1. PubSub
  • 下载 npm install pubsub-js --save
  • 发送数据:
import PubSub from "pubsub-js";
// 接收二个参数,第一个是要发送的消息,让订阅,第二个是传输的数据。
Pubsub.publish("updateSelectedKey", key);
  • 接收数据:
import PubSub from "pubsub-js";
// 组件加载完成时,订阅
componentDidMount() {
  this.pubsub = PubSub.subscribe('updateSelectedKey', (msg, key) => {
    this.setState({
      currentRoute: key
    });
  })
}
// 取消订阅
componentWillUnmount() {
  PubSub.unsubscribe(this.pubsub);
}
  1. ref

    import React, { Component, createRef, useRef } from 'react';
    import Child from './child';
    class Parent extends Component {
    
      constrator(props) {
         super(props);
         this.state = {
             name: ''
         }
         // 1.创建ref
         this.childRef = createRef();
      }
      // 函数组件
      // const childRef = useRef();
    
      componentDidMount() {
         // 3.获取ref
         // 如果是自定义组件,获取到是组件实例
         // 如果是dom元素,获取到是dom节点
         console.log(this.childRef.current);
         // 4.子传父
         this.setState({
             name: this.childRef.current.name
         })
         // 5.父传子
         this.childRef.current.setName('ShangQiao')
      }
    
      render() {
         return {
             <div>
                 <!-- 2.绑定ref -->
                 <Child ref={this.childRef}></Child>
             </div>
         }
      }
    }
    
    
  2. forwardRef

// 子组件(通过forwardRef方法创建)
const Child = React.forwardRef((props, ref) => <input forwardRef={ref} />);

// 父组件
class Father extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  componentDidMount() {
    console.log(this.myRef.current);
  }
  render() {
    return <Child ref={this.myRef} />;
  }
}

注意:

  • ref 在函数式组件上不可使用,函数式组件无实例,但是其内部的 dom 节点和类组件可以使用;
  • 可以通过 ReactDOM.findDOMNode(),入参是一个组件或 dom 节点,返回值的组件对应的 dom 根节点或 dom 节点本身。
    通过 refs 获取到组件实例后,可以通过此方法来获取其对应的 dom 节点;
  1. redux
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪 风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值