消息的订阅与发布(子组件间的通信)
一般我们在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} /> <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} /> <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> ) } }
用这种消息订阅与发布的方式:可以快速实现组件之间的通信,不用借助父组件,无论多深层次的组件都可以快速实现通信。