PubSubJS库介绍
如果你想在React
中使用第三方库来实现Pub/Sub
机制,PubSubJS
是一个不错的选择。它是一个轻量级的库,可以在浏览器和Node.js
环境中使用。
PubSubJS
提供了一个简单的API
,可以让你在应用程序中订阅和发布消息。你可以使用npm
来安装它:
npm install pubsub-js
1-引入使用
import PubSub from 'pubsub-js'
2-首先订阅消息
PubSub.subscribe('List',function(msg, data){ console.log(msg, data)})
用于接收发布的信息。
3-发布消息
PubSub.publish('List',data)
4-取消订阅消息
PubSub.unsubscribe(this.token)
案例使用
现在有一个页面,有两个兄弟组件
Search
组件获取输入的关键字,然后交给List
组件去网络请求。List
组件展示github
的用户列表
1-App组件代码
import React, { Component } from 'react' import Search from './components/Search' import List from './components/List' export default class App extends Component { render() { return ( <div className="container"> <Search/> <List/> </div> ) } }
2-Search组件代码
import React, { Component } from 'react' import PubSubJs from 'pubsub-js' export default class Search extends Component { searchHandle = () => { const {KeyVal:{value}} = this PubSubJs.publish('getSearchVal',value) } render() { return ( <section className="jumbotron"> <h3 className="jumbotron-heading">Search Github Users</h3> <div> <input ref={c=>this.KeyVal = c} type="text" placeholder="关键字"/> <button onClick={this.searchHandle}>Search</button> </div> </section> ) } }
3-List组件代码
import React, { Component } from 'react' import PubSubJs from 'pubsub-js' import axios from 'axios' import './index.css' export default class List extends Component { state = { users: [], isFirst: true, isLoading: false, err: '', } getSearchFunc = (msg, data) => { console.log('接收的信息', data) this.setState({ users: [], isFirst: false, isLoading: true }) axios .get(`https://api.github.com/search/users?q=${data}`) .then( (res) => { this.setState({ users: res.data.items, isFirst: false, isLoading: false }) console.log('请求成功了', res.data) }, (err) => { console.log('请求失败了', err) this.setState({isFirst: false, isLoading: false,err:err.message }) } ) .catch(() => {}) } componentDidMount() { this.token = PubSubJs.subscribe('getSearchVal', this.getSearchFunc) } componentWillUnmount() { PubSubJs.unsubscribe(this.token) } render() { const { users, isFirst, isLoading, err } = this.state return ( <div className="row"> {isFirst ? ( <h2>欢迎搜索</h2> ) : isLoading ? ( <h2>Loading...</h2> ) : err ? ( <h3>{err}</h3> ) : ( users.map((userObj) => { return ( <div className="card" key={userObj.id}> <a href={userObj.html_url} target="_blank" rel="noreferrer"> <img alt="头像" src={userObj.avatar_url} style={{ width: '100px' }} /> </a> <p className="card-text">{userObj.login}</p> </div> ) }) )} </div> ) } }
4-效果展示
总结
1- 设计状态时要考虑全面,例如有网络请求的时候要考虑网络延迟和请求失败的状态处理。
2- ES6小知识点:解构赋值 + 重命名
let obj = {a:{b:1}} const { a } = obj // 传统的解构赋值 const { a:{b} } = obj // 连续的解构赋值 const { a:{b:value} } = obj // 连续解构赋值 + 重命名
3- 消息订阅与发布机制
I. 先订阅,再发布 (一种隔空对话的感觉)
II. 适用于任意组件的通信
III. 要在组件componentWillUnmount
生命钩子中取消订阅
4- 扩展fetch发送请求(关注分离的设计思想)
async func () { try { const res = await fetch('url') const data = await res.json() console.log(data) } catch(error) { console.log(error) } }