源码地址:https://github.com/BLKNjyty/reactstudy
React本身只关注于界面, 并不包含发送ajax请求的代码
前端应用需要通过ajax请求与后台进行交互(json数据)
react应用中需要集成第三方ajax库(或自己封装)
jQuery: 比较重, 如果需要另外引入不建议使用
axios: 轻量级, 建议使用
封装XmlHttpRequest对象的ajax
promise风格
可以用在浏览器端和node服务器端
axios.get('/user?ID=12345')
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
axios.get('/user', {
params: {
ID: 12345
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
伪造服务器,资料:05-所需服务器。作为我们发送给github的代理。
案例样例:搜索用户名,返回githubd的样例
数据传递:父子=》props,兄弟=》使用props,消息由子传递给父再传递给子
const proxy = require('http-proxy-middleware')
module.exports = function(app){
app.use(
proxy('/api1',{ //遇见/api1前缀的请求,就会触发该代理配置
target:'http://localhost:5000', //请求转发给谁
changeOrigin:true,//控制服务器收到的请求头中Host的值
pathRewrite:{'^/api1':''} //重写请求路径(必须)
})
)
}
export default class App extends Component{
state={
users:[],
isFirst:true,
isLoading:false,
err:'',
}
updateAppState=(stateObj)=>{
this.setState(stateObj)
}
render(){
return (
<div className="container">
<Search updateAppState={this.updateAppState}/>
<List {...this.state}/>
</div>
)
}
}
export default class Search extends Componet{
search=()=>{
const {keyWordElement:{value:keyword}}=this
this.props.updateAppState({isFirst:fasle,isLoading:true})
axios.get(`/api1/search/users`q=${keyWord}).then(
response=>{
this.props.updateAppState({isLoading:false,users:response.data.items})
},
error=>{
this.props.updateAppState({isLoading:false,err:error.message})
}
)
}
render(){
return (
<section>
<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 class List extends Component {
render(){
const {users,isFirst,isLoading,err} = this.props
return (
<div className="row">
{
isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</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>
)
}
}
任意组件之间的消息通信。
之前消息通讯只能是:父子组件通过props属性
工具库: PubSubJS
下载: npm install pubsub-js --save
使用:
1) import PubSub from 'pubsub-js' //引入
2) PubSub.subscribe('delete', function(data){ }); //订阅
3) PubSub.publish('delete', data) //发布消息
由于由订阅发布功能,那么list组件的数据状态自己保存即可,不需要交给app了
export default class App extends Component {
render() {
return (
<div className="container">
<Search/>
<List/>
</div>
)
}
}
export default class List extends Component {
state = { //初始化状态
users:[], //users初始值为数组
isFirst:true, //是否为第一次打开页面
isLoading:false,//标识是否处于加载中
err:'',//存储请求相关的错误信息
}
//只要有人发布主题atguigu,执行后边的函数:第一个参数是订阅主题,第二个参数是收到的消息
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>欢迎使用,输入关键字,随后点击搜索</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>
)
}
}
export default class Search extends Component {
search=()=>{
const {keyWordElement:{value:keyword}}=this
PubSub.publish('heiheihei',{isFirst:false,isLoading:true})
axios.get(`/api1/search/users?q=${keyWord}`).then(
response=>{
//请求成功后通知List更新状态
PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
},
error=>{
//请求失败后通知App更新状态
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="输入关键词点击搜索"/>
<button onClick={this.search}>搜索</button>
</div>
</section>
)
}
}
- fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
- 老版本浏览器可能不支持
- 是Promise风格的
search = async()=>{
//发送网络请求---使用fetch发送(优化)
try {
const response= await fetch(`/api1/search/users2?q=${keyWord}`)
const data = await response.json()
console.log(data);
PubSub.publish('atguigu',{isLoading:false,users:data.items})
} catch (error) {
console.log('请求出错',error);
PubSub.publish('atguigu',{isLoading:false,err:error.message})
}
}
本文内容参考b站尚硅谷 链接