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);
}
  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Native 中使用 TypeScript 和 Axios 实现查询功能的步如下: 1. 安装所需的依赖: ``` npm install axios ``` 2. 创建一个查询组件(SearchComponent.tsx)。 ```tsx import React, { useState } from 'react'; import { Button, TextInput, View } from 'react-native'; import axios from 'axios'; interface SearchComponentProps { onSearch: (searchTerm: string) => void; } const SearchComponent: React.FC<SearchComponentProps> = ({ onSearch }) => { const [searchTerm, setSearchTerm] = useState(''); const handleSearch = async () => { try { const response = await axios.get(`https://api.example.com/search?term=${searchTerm}`); // 在这里处理查询结果 console.log(response.data); onSearch(searchTerm); } catch (error) { // 处理错误情况 console.error(error); } }; return ( <View> <TextInput value={searchTerm} onChangeText={(text) => setSearchTerm(text)} /> <Button title="Search" onPress={handleSearch} /> </View> ); }; export default SearchComponent; ``` 3. 在父组件中使用查询组件并处理查询逻辑。 ```tsx import React from 'react'; import { View, Text } from 'react-native'; import SearchComponent from './SearchComponent'; const ParentComponent: React.FC = () => { const handleSearch = (searchTerm: string) => { // 在这里处理查询逻辑,可以更新状态或进行其他操作 console.log('查询关键词:', searchTerm); }; return ( <View> <Text>查询功能示例</Text> <SearchComponent onSearch={handleSearch} /> </View> ); }; export default ParentComponent; ``` 4. 在应用的入口文件中渲染父组件。 ```tsx import React from 'react'; import { AppRegistry } from 'react-native'; import ParentComponent from './ParentComponent'; const App: React.FC = () => { return <ParentComponent />; }; AppRegistry.registerComponent('MyApp', () => App); ``` 以上是一个简单的查询功能的实现示例,你可以根据实际需求进行相应的修改和扩展。记得根据你的项目需要进行网络请求的配置,例如设置请求头、身份验证等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值