8_react组件通信的方式

一、 父子组件(类组件和函数组件中都可)
  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

猜你喜欢

转载自blog.csdn.net/weixin_42465316/article/details/129292139