github搜索案例(axios、pubsub、fetch)
2.github搜索案例(axios、pubsub、fetch)
目录结构
实现效果:
2.1使用axios发送请求
App.jsx
class App extends Component {
state = {
users: [], // 初始化状态,users初始值为数组
isFirst: true, // 是否为第一次打开页面
isLoading: false, //标识是否处于加载中
err: '', //存取请求相关的信息
}
// 更新APP的state
updateAppState = (stateObj) => {
console.log(stateObj)
this.setState(stateObj)
}
render() {
return (
<div className="container">
<Search updateAppState={this.updateAppState} />
<List {...this.state}/>
</div>
);
}
}
Search.jsx
class Search extends Component {
componentDidMount() {
let obj = {a:{b:{c:1}}}
// 连续解构赋值
const {a:{b:{c}}} = obj
console.log(c)
// 连续解构赋值并重命名
let obj2 = {a:{b:2}}
const {a:{b:data}} = obj2
console.log(data)
}
search = () => {
// 获取用户的输入
// 连续解构赋值+重命名
const {keyWordElement:{value:keyWord}} = this
console.log(keyWord)
// 发送请求前通知APP更新状态
this.props.updateAppState({isFirst:false, isLoading:true})
// 发送网络请求
axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
res=>{
// 请求成功通知APP更新状态
this.props.updateAppState({users: res.data.items, isLoading:false})
},
err=>{
// 请求失败通知APP更新状态
this.props.updateAppState({err: err.message, isLoading:false})
})
}
render() {
return (
<section className="jumbotron">
<h3 className="jumbotron-heading">搜索GitHub用户</h3>
<div>
<input ref={c=>this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>
<button onClick={this.search}>搜索</button>
</div>
</section>
);
}
}
List.jsx
class List extends Component {
render() {
const {users, isFirst, isLoading, err} = this.props
return (
<div className="row">
{/*多重三元表达式*/}
{isFirst ? <h2>Welcome to losantu</h2> :
isLoading ? <h2>Loading...</h2> :
err ? <h2>{err}</h2> :
users.map(user => {
return (
<div className="card" key={user.id}>
<a href={user.html_url} target="_blank" rel="noreferrer">
<img alt='head_portrait' src={user.avatar_url}
style={{width: "100px"}}/>
</a>
<p className="card-text">{user.login}</p>
</div>
)
})
}
</div>
);
}
}
2.2使用pubsub发布订阅更新。
npm install pubsub-js --save
不需要在父组件App.jsx上写updateAppState方法了
Search.jsx
class Search extends Component {
componentDidMount() {
let obj = {a:{b:{c:1}}}
// 连续解构赋值
const {a:{b:{c}}} = obj
console.log(c)
// 连续解构赋值并重命名
let obj2 = {a:{b:2}}
const {a:{b:data}} = obj2
console.log(data)
}
search = () => {
// PubSub.publish('state',{name:'tom', age:18})
// 获取用户的输入
// 连续解构赋值+重命名
const {keyWordElement:{value:keyWord}} = this
console.log(keyWord)
// 发送请求前通知List更新状态
// 发布一条主题为state的数据
PubSub.publish('state',{isFirst:false, isLoading:true})
axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
res=>{
// 请求成功通知List更新状态
PubSub.publish('state',{users: res.data.items, isLoading:false})
},
err=>{
// 请求失败通知List更新状态
PubSub.publish('state',{err: err.message, isLoading:false})
})
}
render() {
return (
<section className="jumbotron">
<h3 className="jumbotron-heading">搜索GitHub用户</h3>
<div>
<input ref={c=>this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/>
<button onClick={this.search}>搜索</button>
</div>
</section>
);
}
}
List.jsx
class List extends Component {
state = {
users: [], // 初始化状态,users初始值为数组
isFirst: true, // 是否为第一次打开页面
isLoading: false, //标识是否处于加载中
err: '', //存取请求相关的信息
}
componentDidMount() {
// 订阅state主题,获取发布该主题的数据
this.token = PubSub.subscribe('state', (msg,data)=>{
console.log(data)
this.setState(data)
})
}
componentWillUnmount() {
PubSub.unsubscribe(this.token)
}
render() {
const {users, isFirst, isLoading, err} = this.state
return (
<div className="row">
{ isFirst ? <h2>Welcome to losantu</h2> :
isLoading ? <h2>Loading...</h2> :
err ? <h2>{err}</h2> :
users.map(user => {
return (
<div className="card" key={user.id}>
<a href={user.html_url} target="_blank" rel="noreferrer">
<img alt='head_portrait' src={user.avatar_url}
style={{width: "100px"}}/>
</a>
<p className="card-text">{user.login}</p>
</div>
)
})
}
</div>
);
}
}
2.3使用fetch发送请求
修改search方法
search = async () => {
// PubSub.publish('state',{name:'tom', age:18})
// 获取用户的输入
// 连续解构赋值+重命名
const {keyWordElement:{value:keyWord}} = this
console.log(keyWord)
// 发送请求前通知List更新状态
PubSub.publish('state',{isFirst:false, isLoading:true})
//#region 发送网络请求---使用axios发送
// axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(
// res=>{
// // 请求成功通知List更新状态
// PubSub.publish('state',{users: res.data.items, isLoading:false})
// },
// err=>{
// // 请求失败通知List更新状态
// PubSub.publish('state',{err: err.message, isLoading:false})
// })
//#endregion
//#region 发送网络请求---使用fetch发送(未优化版本)
// fetch(`https://api.github.com/search/users?q=${keyWord}`).then(
// res=>{
// console.log('联系服务器成功了', res)
// return res.json()
// },
// err=>{
// console.log('联系服务器失败了', err)
// return new Promise(()=>{})
// },
// ).then(
// res=>{console.log('获取数据成功了', res)},
// err=>{console.log('获取数据失败了', err)},
// )
//#endregion
//#region 发送网络请求---使用fetch发送(优化版本)
// fetch(`https://api.github.com/search/users?q=${keyWord}`).then(
// res=>{
// console.log('联系服务器成功了', res)
// return res.json()
// },
// ).then(
// res=>{console.log('获取数据成功了', res)},
// ).catch(
// err=>{console.log('请求错误', err)}
// )
//#endregion
//#region 发送网络请求---使用fetch发送(await try catch优化版本)
try {
const res = await fetch(`https://api.github.com/search/users?q=${keyWord}`)
const data = await res.json()
PubSub.publish('state',{users: data.items, isLoading:false})
} catch (err) {
console.log('出错了', err)
PubSub.publish('state',{err: err, isLoading:false})
}
//#endregion
}