效果

 代码

 index.js

//引入react核心库
import React from "react";
//引入ReactDOM
import ReactDOM from "react-dom";
//引入App
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));

App.jsx

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

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

export default class Search extends Component {
  search = () => {
    //获取用户的输入(连续解构赋值+重命名)
    const {
      keyWordElement: { value: keyWord },
    } = this;
    //发送请求前通知List更新状态
    PubSub.publish("updataState", { isFirst: false, isLoading: true });
    //发送网络请求
    axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
      (response) => {
        //请求成功后通知List更新状态
        PubSub.publish("updataState", {
          isLoading: false,
          users: response.data.items,
        });
      },
      (error) => {
        //请求失败后通知App更新状态
        PubSub.publish("updataState", { isLoading: false, err: error.message });
      }
    );
  };

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

List/index.jsx

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("updataState", (_, stateObj) => {
      this.setState(stateObj);
    });
  }

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

List/index.css

.album {
  min-height: 50rem; /* Can be removed; just added for demo purposes */
  padding-top: 3rem;
  padding-bottom: 3rem;
  background-color: #f7f7f7;
}

.card {
  float: left;
  width: 33.333%;
  padding: .75rem;
  margin-bottom: 2rem;
  border: 1px solid #efefef;
  text-align: center;
}

.card > img {
  margin-bottom: .75rem;
  border-radius: 100px;
}

.card-text {
  font-size: 85%;
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>github搜索小案例</title>
    <link rel="stylesheet" href="/css/bootstrap.css" />
    <style>
      .atguigu {
        background-color: rgb(209, 137, 4) !important;
        color: white !important;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

使用vue搭建同样的GitHub搜索案例

Vue实现的github搜索小案例

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐