React-通信方式
写在前面:此笔记跟随尚硅谷课程学习所写
前端请求数据的方式
-
React本身只关注于界面, 并不包含发送ajax请求的代码 -
前端应用需要通过ajax请求与后台进行交互(json数据) -
react应用中需要集成第三方ajax库(或自己封装)
常用的ajax库
- jQuery: 比较重, 如果需要另外引入不建议使用
- axios: 轻量级, 建议使用
axios 是基于promise 的网络请求库,可以用在浏览器端和node服务端,在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
axios
主要特性
- 从浏览器创建 XMLHttpRequests对象
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
安装与导入
npm install axios
import axios from 'axios'
使用方式
客户端 axios使用 get请求
1. 带参数方式1
axios.get('/user/1234/jack')
.then(res=>{
console.log(res.data)
}).catch(err=>{
console.log(err)
})
或者
axios.get('/user/1234/jack').then(
response=>{
console.log(response.data)
},
error=>{
console.log(error.message)
})
2. 带参数方式2
axios.get('/user',{
params: {
id:12334,
name:'jack'
}
}).then(res=>{
console.log(res.data)
}).catch(err=>{
console.log(err)
})
3. 带参数方式3
axios({
method:'GET',
url:'/user',
params:{
id:12334,
name:'jack'
}
responseType: 'stream'
}).then(res=>{
console.log(res.data)
}).catch(err=>{
console.log(err)
})
4. 多个请求并发的时候
function reqSend1(){
axios.get('/user/1234')
}
function reqSend2(){
axios.get('/users/asd')
}
Promise.all([reqSend1(),reqSend2()])
.then(results=>{
console.log(results)
})
axios使用 post请求
1.post 请求方式1
axios.post('/user',{
firstName:'jack',
lastName:'dkj'
}).then(res=>{
console.log(res.data)
}).catch(err=>{
console.log(err.message)
})
2. post请求方式2
axios({
method:'post',
url:'/user/12hdu',
data:{
username:'qxf',
password:'cbdcdhhufv'
}
}).then(res=>{
console.log(res.data)
}).catch(err=>{
console.log(err.message)
})
案列分析: 现在有一个需求,一个输入框一个按钮,在按钮输入内容后点击搜索,发起请求 以gitHub 的用户搜索为例 地址为:https://api.github.com/search/users?q=&{输入框的内容} 点击搜索后获取请求的数据 实现如下:
import React, { Component } from 'react'
import { Button} from 'antd'
import axios from 'axios'
export default class Search extends Component {
handleSearch=()=>{
const {value} = this.keyWordElement
axios.get(`https://api.github.com/search/users?q=${value}`).then(
response=>{
console.log(response.data)
},
error=>{
console.log(error.response)
}
)
}
render() {
return (
<div>
<input ref={c=>this.keyWordElement=c} type="text" placeholder="输入关键词点击搜索" style={{width:'300px'}}/>
<Button onClick={this.handleSearch}>搜索</Button>
</div>
)
}
}
消息订阅-发布机制
举个列子: 订阅报纸: 1.交钱,说好地址,订阅哪一种报纸 2.邮递员送报纸 订阅消息: 1.消息名 2.发布消息 综上所述 ,组件之间的通信就是要先订阅消息,才能发布消息
1.工具库: PubSubJS
2.下载: npm install pubsub-js --save
3.使用:
1)import PubSub from 'pubsub-js'
2)PubSub.subscribe('delete', function(data){ });
3)PubSub.publish('delete', data)
举例: 现在有一个需求 有一个 Search 组件 包含输入框 和按钮 点击搜索按钮 输入内容点击搜索 向gitHub 发送请求 获取数据传递给 List 组件展示 有一个 List 组件 将 向gitHub 发送请求 获取的数据展示出来
以前的方法思想 子组件---->父组件—>子组件
1. app.jsx 定义初始状态 向Search组件传递 一个函数 updateAppState()
2. Search组件发送请求获取数据 通过this.props.updateAppState("请求的数据") 将数据传递给app.jsx
3. 将 Search()函数 改变后的状态值 传递给List组件 展示信息
现在可以通过发布-订阅模式 不通过父组件的方式 直接实现子组件之间的信息传递。 那么现在方法是:
1. Search 组件发送请求获取数据 发布消息传递数据
2. List 组件 定义初始数据状态 ,订阅消息接收数据,更新数据状态,展示消息
App.jsx
import React,{Component} from 'react'
import Search from './component/Search'
import List from './component/List'
export default class App extends Component{
render(){
return(
<div>
<Search/>
<List/>
</div>
)
}
}
Search/index.jsx 发布消息
import React, { Component } from 'react'
import { Button} from 'antd'
import PubSub from 'pubsub-js'
import axios from 'axios'
export default class Search extends Component {
handleSearch=()=>{
const {value} = this.keyWordElement
console.log(value)
PubSub.publish('atguigu',{isFirst:false,isLoading:true})
axios.get(`https://api.github.com/search/users?q=${value}`).then(
response=>{
console.log(response.data)
PubSub.publish('atguigu',{isLoading:false,users:response.data.items})
},
error=>{
PubSub.publish('atguigu',{isLoading:false,err:error.message})
}
)
}
render() {
return (
<div>
<input ref={c=>this.keyWordElement=c} type="text" placeholder="输入关键词点击搜索" style={{width:'300px'}}/>
<Button onClick={this.handleSearch}>搜索</Button>
</div>
)
}
}
List/index.jsx 订阅消息
import React,{Component} from 'react'
import PubSub from 'pubsub-js'
export default class List extends Component{
state={
isFirst:true,
isLoading :false,
users:[],
err:''
}
componentDidMount(){
this.toaken = PubSub.subscribe('atguigu',(_,stateObj)=>{
this.setState(stateObj)
})
}
componentWillUnmount(){
PubSub.unsubscribe(this.token)
}
render() {
const {users,isFirst,isLoading,err} = this.state
return (
<div >
{
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>
)
}
}
fetch发送请求
发送请求的几种方式:
- xhr --------------XMLHttpRequest
(1)首次创建对象
const xhr = new XMLHttpRequest()
(2)打开请求
xhr.open('GET','/user/1234',true)
(3)回调函数
xhr.onload = function() {
console.log(xhr.response);
};
xhr.onerror = function() {
console.log("Oops, error");
};
(4) 发送请求
xhr.send()
- JQuery ------ajax发送请求
$.get(url, data, func, dataType);
1)url:链接地址,字符串表示
2)data:需要发送到服务器的数据,格式为{A: '...', B: '...'}
3)func:请求成功后,服务器回调的函数;function(data, status, xhr),其中data为服务器回传的数据,status为响应状态,xhr为XMLHttpRequest对象,个人感觉关注data参数即可
4)dataType:服务器返回数据的格式
&.get('/user/1234',
{id:id,name:name},
function(data){
},
'json'
)
- axios 发送请求
axios.get(`https://api.github.com/search/users?q=${value}`).then(
response=>{
console.log(response.data)
},
error=>{
console.log(error.response)
}
)
JQuery 和axios都是对XMLHttpRequest 对象的封装 使用这两种方法发送请求都需要下载在引入。 现在有另一种方法 ,不需要下载引用,是Window内置方法就有的,也可以发送请求,和XHR地位并列,是不用XHR就可以发送请求的方法。
fetch发送请求
关注分离的设计思想 简单来说就是将一件复杂的事情拆分成多个简单的步骤,进行解决 特点
- fetch: 原生函数,不再使用XmlHttpRequest对象提交ajax请求
- 老版本浏览器可能不支持(所以用的较少)
案列:还是上面的列子 现在换一种fetch 方法请求数据获取信息
Search/index.jsx 发布消息--------fetch 请求----未优化版本
import React, { Component } from 'react'
import { Button} from 'antd'
import PubSub from 'pubsub-js'
import axios from 'axios'
export default class Search extends Component {
handleSearch=()=>{
const {value} = this.keyWordElement
console.log(value)
fectch('`https://api.github.com/search/users?q=${value}`)
.then(
response=>{
console.log('联系服务器成功了',response)
return response.json()
},
error>{
console.log('联系服务器失败了',error)
return new Promise(()=>{})
}
).then(
response=>{
console.log('获取数据成功',response)
},
error=>{
console.log('获取数据失败',error)
}
)
}
render() {
return (
<div>
<input ref={c=>this.keyWordElement=c} type="text" placeholder="输入关键词点击搜索" style={{width:'300px'}}/>
<Button onClick={this.handleSearch}>搜索</Button>
</div>
)
}
}
Search/index.jsx 发布消息--------fetch 请求----优化版本
import React, { Component } from 'react'
import { Button} from 'antd'
import PubSub from 'pubsub-js'
import axios from 'axios'
export default class Search extends Component {
handleSearch=()=>{
const {value} = this.keyWordElement
console.log(value)
try{
const response = await fectch('`https://api.github.com/search/users?q=${value}`)
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})
}
}
render() {
return (
<div>
<input ref={c=>this.keyWordElement=c} type="text" placeholder="输入关键词点击搜索" style={{width:'300px'}}/>
<Button onClick={this.handleSearch}>搜索</Button>
</div>
)
}
}
参考: 1.尚硅谷视频 2.https://axios-http.com/zh/docs/intro
|