github搜索案例(react版本)(消息订阅与发布实现组件通信)

本篇通过消息订阅与发布实现任意组件间通信,来完成github搜索案例。

消息订阅与发布的基本使用

  1. npm install --save pubsub-js,安装第三方库pubsub-js。
  2. import PubSub from "pubsub-js",引入第三方库PubSub。
  3. 订阅消息:id = PubSub.subscribe(消息名,callback),且callback的第一个形参默认是消息名,后面则是开发者自己传入的参数。
  4. 发布消息:PubSub.publish(消息名,开发者的参数)
  5. 取消订阅:PubSub.unsubscribe(id)

代码变更涉及以下文件:

  1. App.js,即App组件。
  2. components/Search/index.jsx,即Search组件。
  3. components/List/index.jsx,即List组件。

在这里插入图片描述

App.js(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>
    )
  }
}

Search/index.jsx(Search组件)

import React, { Component } from 'react';
import PubSub from 'pubsub-js';
import axios from "axios";

export default class index extends Component {

    handleClick = () => {
        const {keywordEle:{value:keyword}} = this;

        PubSub.publish("changeState",{isFirst:false,isLoading:true});

        axios.get(`https://api.github.com/search/users?q=${keyword}`).then(
            response => {
                console.log("请求成功了",response.data);
                PubSub.publish("changeState",{isLoading:false,users:response.data.items});
            },
            error => {
                PubSub.publish("changeState",{isLoading:false,errorMsg:error.message});
            }
        )
    }

    render() {
        const {handleClick} = this;
        return (
            <section className="jumbotron">
                <h3 className="jumbotron-heading">搜索Github用户</h3>
                <div>
                    <input ref={c => this.keywordEle = c} type="text" placeholder="输入关键词"/>&nbsp;
                    <button onClick={handleClick}>搜索</button>
                </div>
            </section>
        )
    }
}

List/index.jsx(List组件)

import React, { Component } from 'react';
import PubSub from 'pubsub-js';
import "./index.css";

export default class index extends Component {

    state = {
        users:[],
        isFirst:true,
        isLoading:false,
        errorMsg:""
    }

    changeState = (msgName,stateObj) => {
        this.setState(stateObj);
    }

    componentDidMount(){
        this.pubId= PubSub.subscribe("changeState",this.changeState)
    }
    
    componentWillUnmount(){
        PubSub.unsubscribe(this.pubId);
    }

    render() {
        const { isFirst,isLoading,users,errorMsg } = this.state;
        return (
            <div className="row">
                {   isFirst ? <h2>欢迎使用,输入关键词,点击按钮即可搜索</h2> :
                    isLoading ? <h2>正在加载...</h2> :
                    errorMsg ? <h2 style={{color:'red'}}>{errorMsg}</h2> :
                    users.map(userObj => {
                        return (
                            <div className="card" key={userObj.id}>
                                <a href={userObj.html_url} target="_blank" rel="noreferrer">
                                    <img alt="avatar" src={userObj.avatar_url} style={{ width: '100px' }} />
                                </a>
                                <p className="card-text">{userObj.login}</p>
                            </div>
                        )
                    })
                }
            </div>
        )
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值