react实现github用户搜索案例(Axios, Pubsub)

需求:

使用React实现一个Github用户搜索页面,通过输入Github的登录名(不包含中文)来搜索对应用户,并展示搜索到的用户头像和登录名。用户可以点击每个用户跳转到其主页。
细节要求:
①初次使用时,显示欢迎词:“欢迎使用,请输入登录名进行搜索”。
②搜索进行中,显示加载状态:“正在加载中,loading等”。
③搜索出现错误时,展示对应的错误信息。
④搜索结果为空时,显示“用户列表为空”。

最终效果

在这里插入图片描述

需求分析:

在这里插入图片描述

可将页面分为四部分:
①App组件:包裹Search,List组件
②Search组件:搜索Github用户。
③List组件:展示用户列表,包含Item组件。
④Item组件:展示每个用户的信息。

具体实现:

需要使用到PubsubJS实现兄弟组件的通信,需要先安装pubsub-js

npm install pubsub-js

还需要的使用到axios发送网路请求,需要先安装axios

npm install axios

目录解构如下
在这里插入图片描述

App.jsx

import { Component } from 'react'
import './app.css'
import List from './components/List'
import Search from './components/Search'

export default class App extends Component {
  render() {
    return (
      <div className="app-container">
        <Search />
        <List />
      </div>
    )
  }
}

app.css

.app-container {
  width: 80%;
  margin: 0 auto;
}

Search组件

index.jsx

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

import './index.css'

export default class Search extends Component {
  handleSearch = () => {
    // 1.获取用户输入,连续解构赋值重命名,得到用户的输入keyWord
    const {
      keyWordNode: { value: keyWord }
    } = this

    PubSub.publish('updateState', { isFirst: false, isLoading: true })

    // 2.发起网络请求
    axios
      .get('https://api.github.com/search/users?q=' + keyWord)
      .then(res => {
        // TODO 需要对数据进行校验

        PubSub.publish('updateState', {
          userList: res.data.items,
          isLoading: false
        })
      })
      .catch(err => {
        PubSub.publish('updateState', {
          err: err.msg
        })
      })
  }
  render() {
    return (
      <div className="search-container">
        <div className="search-box">
          <h2>搜索 Github 用户</h2>
          <div>
            <input ref={c => (this.keyWordNode = c)} type="text" placeholder="请输入用户名" />
            <button onClick={this.handleSearch}>搜索</button>
          </div>
        </div>
      </div>
    )
  }
}

index.css

.search-container {
  height: 150px;
  background-color: #bdc5cd;
  border-radius: 5px;
  position: relative;
}

.search-box {
  position: absolute;
  left: 50px;
  bottom: 30px;
}

.search-box h2 {
  margin: 10px 0;
}

.search-box input {
  margin-right: 5px;
}

List组件

index.jsx

import Pubsub from 'pubsub-js'
import React, { Component } from 'react'

import Item from '../Item'
import './index.css'

export default class List extends Component {
  state = {
    userList: [], // 用户列表
    isFirst: true, // 是否首次加载
    isLoading: false, // 是否在加载
    err: '' // 错误信息
  }

  // 页面挂载完成后订阅事件updateState, 更新state
  componentDidMount() {
    Pubsub.subscribe('updateState', (msg, stateObject) => {
      this.setState(stateObject)
    })
  }

  // 页面将要卸载时取消订阅事件updateState
  componentWillUnmount() {
    Pubsub.unsubscribe('updateState')
  }

  render() {
    const { userList, isFirst, isLoading, err } = this.state
    return 
    <div className="list-container">
    {
    isFirst ? <div>请输入用户登录名搜索</div> : 
    isLoading ? <div>正在加载中...</div> : 
    err ? <div style={{ color: 'red' }}>{err}</div> : 
    userList.length === 0 ? <div>用户列表为空</div> : 
    userList.map(item => <Item key={item.id} item={item} />)
    }
    </div>
  }
}

index.css

.list-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 10px;
  padding: 15px 0 0 0;
}

Item组件

import React, { Component } from 'react'
import './index.css'

export default class Item extends Component {
  handleClickUser = item => {
    return () => {
      // 跳转到用户的github主页
      window.open(item.html_url)
    }
  }
  render() {
    const { item } = this.props
    return (
      <div className="item-container" onClick={this.handleClickUser(item)}>
        <img src={item.avatar_url} style={{ width: '80px', height: '80px', borderRadius: '5px' }} alt="" />
        <span>{item.login}</span>
      </div>
    )
  }
}

index.css

.item-container {
  height: 120px;
  background-color: #bdc5cd;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.item-container:hover {
  cursor: pointer;
  background-color: rgba(241, 7, 7, 0.192);
}

相关推荐

  1. React查询、搜索类功能的实现

    2024-07-15 23:50:02       56 阅读
  2. React查询、搜索类功能的实现

    2024-07-15 23:50:02       52 阅读
  3. react实现表格多条件搜索

    2024-07-15 23:50:02       45 阅读
  4. react实现组件通信的案例

    2024-07-15 23:50:02       43 阅读
  5. React18-列表数据实现用户删除、批量删除

    2024-07-15 23:50:02       51 阅读
  6. GitHub高级搜索技巧

    2024-07-15 23:50:02       47 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-15 23:50:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-15 23:50:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-15 23:50:02       58 阅读
  4. Python语言-面向对象

    2024-07-15 23:50:02       69 阅读

热门阅读

  1. Kafka配置SSL信道加密

    2024-07-15 23:50:02       21 阅读
  2. TensorFlow 的基本概念和使用场景

    2024-07-15 23:50:02       18 阅读
  3. IT专业入门,高考假期预习指南

    2024-07-15 23:50:02       16 阅读
  4. 面试必备!Redis面试题合集

    2024-07-15 23:50:02       19 阅读
  5. 面试题 25. 合并两个排序的链表

    2024-07-15 23:50:02       14 阅读
  6. C# 1.方法

    2024-07-15 23:50:02       20 阅读
  7. Neo4j数据库相关

    2024-07-15 23:50:02       19 阅读
  8. PYTHON自学班车(三)NUMPY

    2024-07-15 23:50:02       20 阅读
  9. C语言从头学31——与字符串变量相关的几个函数

    2024-07-15 23:50:02       24 阅读
  10. C++版OpenCV_01_图像数字化

    2024-07-15 23:50:02       21 阅读
  11. NAT实验

    NAT实验

    2024-07-15 23:50:02      15 阅读