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組件
import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import axios from 'axios'
export default class Search extends Component {
search = ()=>{
//獲取用戶的輸入(連續(xù)解構(gòu)賦值+重命名)
const {keyWordElement:{value:keyWord}} = this
//發(fā)送請(qǐng)求前通知List更新?tīng)顟B(tài)
PubSub.publish('atguigu',{isFirst:false,isLoading:true})
//發(fā)送網(wǎng)絡(luò)請(qǐng)求
axios.get(`/api1/search/users?q=${keyWord}`).then(
response => {
//請(qǐng)求成功后通知List更新?tīng)顟B(tài)
PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
},
error => {
//請(qǐng)求失敗后通知App更新?tīng)顟B(tài)
PubSub.publish('atguigu',{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="輸入關(guān)鍵詞點(diǎn)擊搜索"/>
<button onClick={this.search}>搜索</button>
</div>
</section>
)
}
}
List組件
import React, { Component } from 'react'
import PubSub from 'pubsub-js'
import './index.css'
export default class List extends Component {
state = { //初始化狀態(tài)
users:[], //users初始值為數(shù)組
isFirst:true, //是否為第一次打開(kāi)頁(yè)面
isLoading:false,//標(biāo)識(shí)是否處于加載中
err:'',//存儲(chǔ)請(qǐng)求相關(guān)的錯(cuò)誤信息
}
componentDidMount(){
this.token = PubSub.subscribe('atguigu',(_,stateObj)=>{
this.setState(stateObj)
})
}
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
render() {
const {users,isFirst,isLoading,err} = this.state
return (
<div className="row">
{
isFirst ? <h2>歡迎使用二庵,輸入關(guān)鍵字钳幅,隨后點(diǎn)擊搜索</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>
)
}
}