1. 理解
1.1. 前置说明
- React本身只关注于界面, 并不包含发送ajax请求的代码
- 前端应用需要通过ajax请求与后台进行交互(json数据)
- react应用中需要集成第三方ajax库(或自己封装)
- jQuery: 比较重, 如果需要另外引入不建议使用
- axios: 轻量级, 建议使用
1.2. 常用的ajax请求库
1) 封装XmlHttpRequest对象的ajax
2) promise风格
3) 可以用在浏览器端和node服务器端
2. axios
2.1. 文档
地址: https://github.com/axios/axios
安装axios: npm install axios
2.2. 相关API
1)GET请求
1 axios.get('/user?ID=12345') 2 .then(function (response) { 3 console.log(response.data); 4 }) 5 .catch(function (error) { 6 console.log(error); 7 }); 8 9 axios.get('/user', { 10 params: { 11 ID: 12345 12 } 13 }) 14 .then(function (response) { 15 console.log(response); 16 }) 17 .catch(function (error) { 18 console.log(error); 19 });
2)POST请求
1 axios.post('/user', { 2 firstName: 'Fred', 3 lastName: 'Flintstone' 4 }) 5 .then(function (response) { 6 console.log(response); 7 }) 8 .catch(function (error) { 9 console.log(error); 10 });
3. 案例
分析:
1.设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办。
2.ES6小知识点:解构赋值+重命名
let obj = {a:{b:1}}
const {a} = obj; //传统解构赋值
const {a:{b}} = obj; //连续解构赋值
const {a:{b:value}} = obj; //连续解构赋值+重命名
3.消息订阅与发布机制
1.先订阅,再发布(理解:有一种隔空对话的感觉)
2.适用于任意组件间通信
3.要在组件的componentWillUnmount中取消订阅
4.fetch发送请求(关注分离的设计思想)
try {
const response= await fetch(`/api1/search/users?q=${keyWord}`)
const data = await response.json()
console.log(data);
} catch (error) {
console.log('请求出错',error);
}
(1)App.jsx
1 import React, { Component } from 'react' 2 import Search from './components/Search' 3 import List from './components/List' 4 5 export default class App extends Component { 6 7 state = { //初始化状态 8 users:[], //users初始值为数组 9 isFirst:true, //是否为第一次打开页面 10 isLoading:false,//标识是否处于加载中 11 err:'',//存储请求相关的错误信息 12 } 13 14 //更新App的state 15 updateAppState = (stateObj)=>{ 16 this.setState(stateObj) 17 } 18 19 render() { 20 return ( 21 <div className="container"> 22 <Search updateAppState={this.updateAppState}/> 23 <List {...this.state}/> 24 </div> 25 ) 26 } 27 }
(2) List.jsx
1 import React, { Component } from 'react' 2 import './index.css' 3 4 export default class List extends Component { 5 render() { 6 const {users,isFirst,isLoading,err} = this.props 7 return ( 8 <div className="row"> 9 { 10 isFirst ? <h2>欢迎使用,输入关键字,随后点击搜索</h2> : 11 isLoading ? <h2>Loading......</h2> : 12 err ? <h2 style={{color:'red'}}>{err}</h2> : 13 users.map((userObj)=>{ 14 return ( 15 <div key={userObj.id} className="card"> 16 <a rel="noreferrer" href={userObj.html_url} target="_blank"> 17 <img alt="head_portrait" src={userObj.avatar_url} style={{'100px'}}/> 18 </a> 19 <p className="card-text">{userObj.login}</p> 20 </div> 21 ) 22 }) 23 } 24 </div> 25 ) 26 } 27 }
(3) Search.jsx
1 import React, { Component } from 'react' 2 import axios from 'axios' 3 4 export default class Search extends Component { 5 6 search = ()=>{ 7 //获取用户的输入(连续解构赋值+重命名) 8 const {keyWordElement:{value:keyWord}} = this 9 //发送请求前通知App更新状态 10 this.props.updateAppState({isFirst:false,isLoading:true}) 11 //发送网络请求 12 axios.get(`/api1/search/users?q=${keyWord}`).then( 13 response => { 14 //请求成功后通知App更新状态 15 this.props.updateAppState({isLoading:false,users:response.data.items}) 16 }, 17 error => { 18 //请求失败后通知App更新状态 19 this.props.updateAppState({isLoading:false,err:error.message}) 20 } 21 ) 22 } 23 24 render() { 25 return ( 26 <section className="jumbotron"> 27 <h3 className="jumbotron-heading">搜索github用户</h3> 28 <div> 29 <input ref={c => this.keyWordElement = c} type="text" placeholder="输入关键词点击搜索"/> 30 <button onClick={this.search}>搜索</button> 31 </div> 32 </section> 33 ) 34 } 35 }