消息的订阅与发布(子组件间的通信)

一般我们在React中,子组件与子组件之间的通信我们能想到的费力的实现方式:都是借助父组件中的状态与方法来完成,

如下:

App.js(父组件)

import React, { Component } from 'react'
import Search from './components/Search'
import Content from './components/Content'

export default class App extends Component {
  state = {
    list:'',//存放search子组件传递过来的数据,同时交给Content子组件使用
  }
  // 获取值,传递给子组件Search,用来保存子组件Search获取的数据
  handleInfo  = (list) => {
    this.setState({list})
  }
  
  render() {
    return (
      <div className="container">
        <Search handleInfo={this.handleInfo}/>
        <Content list={this.state.list}/>
      </div>
    )
  }
}
(子组件)src/components/Search/index.jsx
import React, { Component } from 'react'

export default class Search extends Component {
 // 搜索
  search = () => {
    // 获取输入框中数据
    const {value} = this.inputworlds;
    this.props.handleInfo(value);//通过handleInfo方法向App.js传递数据,供子组件Content使用
  }
  
  render() {
    return (
      <section className="jumbotron">
        <h3 className="jumbotron-heading">子组件之间的通信</h3>
        <div>
          <input type="text" placeholder="请输入用户名..." ref={e => this.inputworlds = e} />&nbsp;
          <button onClick={this.search}>搜索</button>
        </div>
      </section>
    )
  }
}
(子组件)src/components/Content/index.jsx
import React, { Component } from 'react'

export default class Content extends Component {

  render() {
  // 获取search子组件传递过来的数据,进行渲染
    const {list} = this.props
    return (
      <div className="row">
        {list}
     </div>
    )
  }
}

上面这种方法,是通过父组件来进行子组件与子组件之间的通信,

1、通过在父组件存放状态、方法,

2、然后子组件1获取的数据通过父组件传递过来的props中的方法,通过this.props.方法名(数据)传递给父组件App.js,

3、父组件App.js再通过这个方法,将数据保存在状态中,再通过props传递给子组件2,子组件2通过父组件传递过来的数据,this.props.XX来使用

 

第二种便捷的组件通信(优化上面的版本):

 消息的订阅与发 

安装插件:

npm install pubsub-js
// 或者
yarn add pubsub-js

 父组件:App.js

import React, { Component } from 'react'
import Search from './components/Search'
import Content from './components/Content'

export default class App extends Component {
  
  render() {
    return (
      <div className="container">
        <Search />
        <Content />
      </div>
    )
  }
}

子组件:src/components/Search.jsx

import React, { Component } from 'react'
// 引入第三方依赖,消息订阅与发布
import PubSub from 'pubsub-js'

export default class Search extends Component {
  // 搜索
  search = () => {
    // 获取输入框中数据
    const {value} = this.inputworlds;
    // 发布消息、PubSub.publish(消息名,数据)
    PubSub.publish('MyMess',value);
  }
  
  render() {
    return (
      <section className="jumbotron">
        <h3 className="jumbotron-heading">Search Github Users</h3>
        <div>
          <input type="text" placeholder="请输入用户名..." ref={e => this.inputworlds = e} />&nbsp;
          <button onClick={this.search}>Search</button>
        </div>
      </section>
    )
  }
}

子组件:src/components/Content.jsx

import React, { Component } from 'react'
import PubSub from 'pubsub-js'

export default class Content extends Component {
  state = {
    list:'',// 存放Search 组件搜索框的值
  }
   // 组件开始渲染之前
  componentDidMount(){
    // 接收订阅的消息 PubSub.subscribe(msg,是订阅消息的名字也就是MyMess;data,是接收Search组件传递过来的数据;一般我们用这个msg有点多余的时候,可以将msg替换成'_')
    this.token = PubSub.subscribe('MyMess',(msg,data) => {
      this.setState(data)
    })
  }
  // 组件将要销毁的时候
  componentWillUnmount(){
    // 取消消息订阅
    PubSub.unsubscribe(this.token);
  }
  render() {
    const {list} = this.state
    return (
      <div className="row">
        {list}
      </div>
    )
  }
}

用这种消息订阅与发布的方式:可以快速实现组件之间的通信,不用借助父组件,无论多深层次的组件都可以快速实现通信。

posted @ 2021-11-23 18:30  一江春水向东刘小姐  阅读(85)  评论(0编辑  收藏  举报