React Ajax Github搜索案例

177 阅读1分钟

功能说明

调用GitHub的接口,查询用户,获取信息并展示。 image.png

配置代理

由于GitHub经常不稳定,就用了个本地服务器的假数据

// CJS 语法
const proxy = require('http-proxy-middleware')

module.exports = function(app){
    app.use(
        proxy.createProxyMiddleware('/api1', {
            // 遇到 /api1 该前缀就会触发该代理配置
            target: 'http://localhost:5000',   // 请求目标地址
            changeOrigin: true,  // 控制服务器收到的请求头中 Host 字段的值 表示请求的来源 
            pathRewrite: {'^/api1': ''}  // 重写请求路径
        })
    )
}

axios 发送请求

search = () => {
    // 获取用户输入
    const { keyWordElement : {value : keyWord} } = this
    // 发送网络请求 https://api.github.com/search/users?q=
    axios.get(`http://localhost:3000/api1/search/users2?q=${keyWord}`).then(
        response => {
            console.log(response.data);
        },
        error => {
            console.log(error);
        }
    )
}

单组件多状态展示

List组件,有几种展示情况

  • 正常的展示 users 数据
  • 一开始的欢迎态
  • 加载态
  • 失败态

处理方法:父组件记录所有状态信息(用一个个变量单独记录每一个状态)并传递给展示数据子组件,子组件用三目运算符选择性展示。

而Search组件做的是什么事情呢?它需要每次把上述的各种状态传给父组件。

消息订阅-发布机制

传统方法

通过父组件为媒介,传递数据。

//传递能够修改数据的方法给子组件1
<Search updateAppState={this.updateAppState}/>

//批量传递数据给子组件2
<List {...this.state}/>

更方便的方法——消息订阅-发布机制

所使用的包 pubsub-js

整体来看简单易用,立即上手。留个坑,有空得去研究一下这玩意是怎么实现的。

订阅消息

componentDidMount(){
    this.token = PubSub.subscribe('my-data', (msg, stateObj) => {
        this.setState(stateObj)
    })
}

componentWillUnmount(){
    PubSub.unsubscribe(this.token)
}

发布消息

axios.get(`http://localhost:3000/api1/search/users?q=${keyWord}`).then(
    response => {
        PubSub.publish('my-data', {
            isLoading: false,
            users: response.data.items
        })
    },
    error => {
        PubSub.publish('my-data', {
            isLoading: false,
            err: error.message
        })
    }
)

fetch 的使用

这个东西使用的比较少,了解即可。

特点

  • 原生内置的对象,无需引入,直接开用
  • 与 xhr 同一级别
  • 内部使用了 promise

使用示例

复杂版本

// 发送网络请求 使用 fetch
fetch(`/api1/search/users?q=${keyWord}`).then(response => {
    console.log('联系服务器成功');
    return response.json()
}).then(response => {
    console.log(response);
    PubSub.publish('my-data', {
        isLoading: false,
        users: response.items
    })
}).catch(e => {
    console.log(e);
})

简单版本

//外部函数需要使用 async 包裹
try {
    const response = await fetch(`/api1/search/users?q=${keyWord}`)
    const data = await response.json()
    PubSub.publish('my-data', {
        isLoading: false,
        users: data.items
    })
} catch (error) {
    console.log(error);
}