基本功能 在搜索框中输入搜索,然后不通过父子传值的方式改为兄弟组件之间传值实现搜索结果的展示。点击搜索后,得到结果之后通知List组件进行界面数据更新 关键代码
1、安装pubsub-js
npm add pubsub-js
2、App.js
import React, { Component } from 'react';
import Search from './components/Search';
import List from './components/List';
class App extends Component {
render() {
return (
<div className="container">
<Search />
<List/>
</div>
);
}
}
export default App;
3、List=>index.js 在componentDidMount中订阅notice通知,记得在页面销毁的时候取消订阅
import React, { Component } from 'react';
import PubSub from 'pubsub-js'
import './index.css'
class List extends Component {
state={
users:[],
isFirst:true,
isLoading:false,
err:''
}
componentDidMount(){
this.token=PubSub.subscribe('notice',(_,stateObj)=>{
this.setState(stateObj)
})
}
componentWillUnmount(){
PubSub.unsubscribe();
}
render() {
const {users,isFirst,isLoading,err}=this.state
return (
<div className="row">
{
isFirst?<h2>欢迎使用,输入关键字,随后点击搜索</h2>:
isLoading?<h2>loading....</h2>:err?<h2 style={{color:'red'}}>{err}</h2>:
users.map(userObj=>{
return(
<div className="card" key={userObj.id}>
<a href={userObj.html_url} target="_blank" rel="noreferrer" >
<img src={userObj.avatar_url} style={{width:'100px'}} alt='head_portrait'/>
</a>
<p className="card-text">{userObj.login}</p>
</div>
)
})
}
</div>
);
}
}
export default List;
4、Search=>index.js 在搜索后需要通知到List组件进行更新
import React, { Component } from 'react';
import PubSub from 'pubsub-js'
import axios from 'axios';
class Search extends Component {
search=()=>{
const{keyWordElement:{value:keyWord}}=this;
console.log(keyWord)
PubSub.publish('notice',{isFirst:false,isLoading:true})
axios.get(`/api1/search/users?q=${keyWord}`).then(response=>{
PubSub.publish('notice',{isLoading:false,users:response.data.items})
},error=>{
PubSub.publish('notice',{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="输入关键词点击搜索"/> <button onClick={this.search}>搜索</button>
</div>
</section>
);
}
}
export default Search;
5、List=>index.css
.album {
min-height: 50rem;
padding-top: 3rem;
padding-bottom: 3rem;
background-color: #f7f7f7;
}
.card {
float: left;
width: 33.333%;
padding: .75rem;
margin-bottom: 2rem;
border: 1px solid #efefef;
text-align: center;
}
.card > img {
margin-bottom: .75rem;
border-radius: 100px;
}
.card-text {
font-size: 85%;
}
代理setProxy.js
const proxy=require('http-proxy-middleware')
module.exports=function(app){
app.use(
proxy('/api1',{
target:'http://localhost:5000',
changeOrigin:true,
pathRewrite:{'^/api1':''}
})
)
}
|