第二十九章 使用消息订阅发布实现组件通信

简介: 第二十九章 使用消息订阅发布实现组件通信

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-效果展示

image.pngimage.png

总结

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)
    }
}


相关文章
|
机器学习/深度学习 算法 数据挖掘
Python 图像处理实用指南:6~10
Python 图像处理实用指南:6~10
729 0
|
5月前
|
Linux 网络安全 Apache
针对在Centos/Linux安装Apache过程中出现的常见问题集锦
以上每个问题的解决方案应深入分析错误日志、系统消息和各种配置文件,以找到根本原因并加以解决。务必保持系统和Apache软件包更新到最新版本,以修复已知的bugs和安全漏洞。安装和管理Web服务器是一项需要细致关注和不断学习的任务。随着技术的发展,推荐定期查看官方文档和社区论坛,以保持知识的更新。
261 80
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
275 0
|
JSON 前端开发 JavaScript
Highcharts 配置选项详细说明
Highcharts 配置选项详细说明
164 2
|
存储 SQL 关系型数据库
数据库设计的基本原则和主要步骤以及应注意什么?
数据库设计的基本原则和主要步骤以及应注意什么?
683 0
|
设计模式 开发者 Python
Python中循环依赖问题及其解决方案
循环依赖是 Python 开发中需要特别注意的问题。通过重新设计模块结构、延迟导入、依赖注入、利用 Python 的动态特性以及代码重构等方法,可以有效地解决循环依赖问题。这些策略不仅有助于提高代码的可维护性和可读性,还能避免潜在的运行时错误。在实际开发中,开发者应该根据具体情况选择合适的解决方案。
|
存储 NoSQL Linux
【MongoDB】下载安装、指令操作
【MongoDB】下载安装、指令操作
516 1
|
开发工具 git
IDEA中怎么将代码提交代码到远程仓库
IDEA中怎么将代码提交代码到远程仓库
207 0
|
canal 存储 缓存
如何优雅的记录操作日志
操作日志几乎存在于每个系统中,而这些系统都有记录操作日志的一套 API。操作日志和系统日志不一样,操作日志必须要做到简单易懂。所以如何让操作日志不跟业务逻辑耦合,如何让操作日志的内容易于理解,如何让操作日志的接入更加简单?上面这些都是本文要回答的问题。我们主要围绕着如何“优雅”地记录操作日志展开描述,希望对从事相关工作的同学能够有所帮助或者启发。
1012 0
如何优雅的记录操作日志
【python】使用python将多个视频合并、延长视频的时间
今天做知识分享的时候,最后保存的视频时长是58分钟,那么如何改变视频的时长,将视频时长改为一个小时呢?请阅读下面的文章。
【python】使用python将多个视频合并、延长视频的时间