消息订阅-发布机制
- 工具库: PubSubJS
- 下载: npm install pubsub-js --save
- 使用:
1)import PubSub from ‘pubsub-js’ //引入
2)PubSub.subscribe(‘delete’, function(data){ }); //订阅
3)PubSub.publish(‘delete’, data) //发布消息
App组件:
import React, {Component} from 'react'
import Search from "./components/Search";
import List from "./components/List";
import './App.css';
export default class App extends Component {render() {return (<div className="container"><Search /><List /></div>)}
}/*function App() {return (<div><Index /></div>);
}*/
Search组件:
import React, {Component} from 'react';
import PubSub from 'pubsub-js'
import axios from "axios";class Search extends Component {search = () => {// 获取用户的输入(连续解构赋值+重命名)const {keyWordElement: {value: keyword}} = this// 发送请求前通知List更新状态// this.props.updateAppState({isFirst: false, isLoading: true})PubSub.publish('zep', {isFirst: false, isLoading: true})// 发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then((response) => {// 请求成功后通知List更新状态// this.props.updateAppState({isLoading: false, users: response.data.items})console.log('Search组件发布消息')PubSub.publish('zep', {isLoading: false, users: response.data.items})},(error) => {// this.props.updateAppState({isLoading: false, err: error.message})PubSub.publish('zep', {isLoading: false, err: error.message})})}render() {return (<section className="jumbotron" style={{textAlign: "center"}}><h3 className="jumbotron-heading">搜索github用户</h3><div><input ref={c => this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> <button onClick={this.search}>搜索</button></div></section>);}
}export default Search;
List组件:
import React, {Component} from 'react';
import PubSub from 'pubsub-js'
import './index.css'class List extends Component {state = {// 初始化状态users: [], // users初始值为数组isFirst: true, // 是否为第一次打开页面isLoading: false, // 标识是否处于加载中err: '' // 存储请求相关的错误信息}componentDidMount() {// 订阅消息this.token = PubSub.subscribe('zep', (msg, stateObj) => {console.log('List组件订阅消息', stateObj)this.setState(stateObj)})}componentWillUnmount() {PubSub.unsubscribe(this.token)}render() {const {users, isFirst, isLoading, err} = this.statereturn (<div className="row">{isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> :isLoading ? <h2>Loading...</h2> :err ? <h2 style={{color: 'red'}}>{err}</h2> :users.map((userObj) => {return (<div className="card" key={userObj.id}><a href={userObj.html_url} rel="noreferrer" target="_blank"><img alt="avatar" src={userObj.avatar_url} style={{width: '100px'}}/></a><p className="card-text">{userObj.login}</p></div>)})}</div>);}
}export default List;