4.4 消息订阅-发布机制
兄弟组件之间的通信
-
工具库 :
PubSubJs
-
下载 :
npm install pubsub-js --save
-
使用:
-- 引入 import PubSub from 'pubsub-js' -- 订阅 this.token = PubSub.subscribe('delete', function(data){}) -- 发布消息 PubSub.publish('delete',data) -- 取消订阅 PubSub.unsubscribe(this.token)
-
示例
import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import axios from 'axios'
export default class Search extends Component {
search = ()=>{
// 发布消息
console.log('search组件发布消息了');
const {keyWordElement:{value:keyword}} = this;
// 发送请求前通知List更新状态
PubSub.publish('atguigu', {isFirst:false, isLoading:true});
// 发送网络请求
axios.get(`/api1/search/users?q=${keyword}`).then(
response => {
PubSub.publish('atguigu',{isLoading:false, users:response.data.items})
},
error => {
PubSub.publish('atguigu', {isLoading:false, err : error.message})
}
)
}
render() {
return (
<section className="jumbotron">
<h3 className="jumbotron-heading">Search Github Users</h3>
<div>
<input ref={c => this.keyWordElement = c} type="text" placeholder="enter the name you search"/>
<button onClick={this.search}>Search</button>
</div>
</section>
)
}
}
import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import './index.css'
export default class List extends Component {
// 初始化状态
state = {
users : [], // users为初始值为数组
isFirst: true, // 是否为第一次打开页面
isLoading:false, // 标识是否处于加载中
err: '' // 存储请求相关的错误信息
}
componentDidMount(){
// 开启定时器、订阅消息
this.token = PubSub.subscribe('atguigu', (msg, data)=>{
console.log('List--',data);
this.setState(data)
})
}
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
render() {
const {users, isFirst, isLoading, err} = this.state
return (
<div className="row">
{
isFirst ? <h2>欢迎使用,输入关键字</h2> :
isLoading ? <h2>Loading....</h2> :
err ? <h2 style={{color:'red'}}>{err}</h2> :
users.map((userObj)=>{
return(
<div key={userObj.id} className="card">
<a rel="noreferrer" href={userObj.html_url} target="_blank">
<img alt='head_portrait' src={userObj.avatar_url} style={{width: '100px'}}/>
</a>
<p className="card-text">{userObj.login}</p>
</div>
)
})
}
</div>
)
}
}