react兄弟组件通信之pubsub-js
-
在未接触redux之前,兄弟组件之间共享状态,需要把状态提升到公共的父组件,然后父组件用props传给子组件,实现兄弟组件状态共享。
还有一种方法可实现兄弟组件的通信,pubsub-js
npm地址:https://www.npmjs.com/package/pubsub-js
pubsub-js就是消息发布订阅,实现这个功能的有很多库
vue2的$bus、mitt.js都是一样的原理,个人觉得比pubsub-js使用起来更加方便
这里用一下pubsub-js
Search组件内 发布消息
import React, { Component } from 'react' import PubSub from 'pubsub-js' import axios from 'axios'; export default class Search extends Component { search = () => { // 获取用户输入 const { value: keyWord } = this.keyWordElement; // 消息发布 // 发送请求前通知List更新状态 PubSub.publish('updateListState', { isFirst: false, isLoading: true, err: '' }) // 获取网络请求 axios.get(`https://api.github.com/search/users?q=${keyWord}`).then( res => { PubSub.publish('updateListState', { users: res.data.items, isLoading: false }) }, err => { // 请求失败后通知List更新错误信息状态 PubSub.publish('updateListState', { err: err.message, isLoading: false }) } ) } render() { return ( <section className="jumbotron"> <h3 className="jumbotron-heading">搜索github用户</h3> <div> <input ref={ c => this.keyWordElement = c } type="text" placeholder="输入搜索的名称" /> <button onClick={this.search}>搜索</button> </div> </section> ) } }
List组件内 订阅消息,在组件销毁时取消订阅
import React, { Component } from 'react' import PubSub from 'pubsub-js' import './index.css' export default class List extends Component { state = { users: [], // 用户列表 isFirst: true, // 是否第一次打开页面 isLoading: false, // 是否加载中 err: '', // 存储错误信息 } componentDidMount() { // 订阅消息 this.token = PubSub.subscribe('updateListState', (_, stateObj) => { this.setState(stateObj); }) } componentWillUnmount() { // 取消订阅 PubSub.unsubscribe(this.token) } render() { const { users, isFirst, isLoading, err } = this.state; return ( isFirst ? <h2>欢迎使用,输入关键字,然后点击搜索</h2> : isLoading ? <h2>Loading......</h2> : err ? <h2 style={{ color: 'red' }}>{err}</h2> : <div className="row"> { users.map(userObj => { return ( <div className="card" key={userObj.id}> <a href={userObj.html_url} target="_blank"> <img src={userObj.avatar_url} style={{width: '100%'}} /> </a> <p className="card-text">{userObj.login}</p> </div> ) }) } </div> ) } }
-
-