在React中发送Ajax请求-axios的使用
React本身不包含发送Ajax的代码,一般使用第三方的库。如axios,这是专门用于ajax请求的库。其封装了XmlHttpRequest对象的ajax,且使用promise风格写法,在浏览器的客户端与服务端都能使用。
你可能会想问为什么不用fetch()原生函数呢?因为考虑到对老版本浏览器的支持情况。
其次,fetch()不使用XmlHttpRequest对象发生ajax请求。
如果你想使用fetch()在低版本浏览器中,你可以考虑使用fetch.js的兼容库。
[axios CDN]
https://cdn.bootcss.com/axios/0.18.0/axios.js
//get方式
axios.get(url) .then(response=>{ }) .catch(error =>{ console.log(error.message) })
//post方式
axios.post(url,{参数对象}) .then(response=>{ console.log(response) }) .catch(error =>{ console.log(error.message) })
示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="test"></div> <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script> <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script> <script src="https://cdn.bootcss.com/axios/0.17.1/axios.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script> <script type="text/babel"> class MostStar extends React.Component { state = { repoName:'', repoUrl: '' } componentDidMount() { //方式1、使用axio发送异步ajax请求 const url = 'https://api.github.com/search/repositories?q=tetris+language:assembly&sort=stars&order=desc' axios.get(url) .then(response => { const result = response.data; const {name,html_url} = result.items[0]; this.setState({repoName:name,repoUrl:html_url}); }) //方式2、使用fetch()发生请求 fetch(url) .then(response => { return response.json() }) .then(data=>{ //得到数据 const {name,html_url} = data.items[0]; this.setState({repoName:name,repoUrl:html_url}); }) } render() { const {repoName,repoUrl} = this.state if(!repoName){ return ( <h2>Loading...</h2> ) }else { return ( <h2>Most star repo is <a href={repoUrl}>{repoName}</a></h2> ) } } } ReactDOM.render(<MostStar/>,document.getElementById('test')) </script> </body> </html>
使用fetch发生请求
fetch使用文档
https://www.bootcdn.cn/fetch/readme/ https://segmentfault.com/a/1190000003810652
用法
fetch(url).then(function(response){ return response.json() }).then(function(data){ console.log(data);//这才是返回的数据 }).catch(function(e){ console.log(e); })
练习:写一个搜索请求##
- 1、初始化react-app
- 2、拆分组件
- 3、编写静态组件
- 4、编写动态组件
index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './components/index.css'; import App from './components/app'; ReactDOM.render(<App />, document.getElementById('root'));
app.jsx
import React, { Component } from 'react' import Search from './search' import Main from './main' class App extends Component { state = { searchName: '' } //更新状态 setSearchName = (searchName) => this.setState({searchName}) render () { return ( <div className="container"> <Search setSearchName={this.setSearchName}/> <Main searchName={this.state.searchName}/> </div> ) } } export default App
search.jsx
import React, { Component } from 'react' import PropTypes from 'prop-types' class Search extends Component { static propTypes = { setSearchName: PropTypes.func.isRequired } handleSearch = () => { //得到输入的关键字 const searchName = this.input.value.trim(); if(searchName){ //搜索 this.props.setSearchName(searchName); } } render () { return ( <section className="jumbotron"> <h3 className="jumbotron-heading">Search Github Users</h3> <div> <input type="text" placeholder="enter the name you search" ref={input=>this.input=input}/> <button onClick={this.handleSearch}>Search</button> </div> </section> ) } } export default Search
main.jsx
import React, { Component } from 'react' import PropTypes from 'prop-types' import axios from 'axios' class Main extends Component { static propTypes = { searchName: PropTypes.string.isRequired } state = { initView: true, loading: false, users: null, errorMsg: null } //当组件接收到新的属性时进行回调 componentWillReceiveProps(newProps) {//指定新的searchName,需要发请求 const {searchName} = newProps; //更新状态 this.setState({ initView:false, loading:true }) //发请求 const url = `https://api.github.com/search/users?q=${searchName}`; axios.get(url) .then(response => { //得到数据 const result = response.data; const users = result.items.map(item=> { return {name:item.login,url:item.html_url,avatarUrl:item.avatar_url}//注意 }) //更新状态 this.setState({ loading:false, users }) }) .catch(error => { //更新状态 this.setState({ loading:false, errorMsg:error.message }) }) } render () { const {initView,loading,users,errorMsg} = this.state; const {searchName} = this.props; if(initView){ return <h2>请输入关键词进行搜索:{searchName}</h2> }else if(loading){ return <h2>正在请求</h2> }else if(errorMsg){ return <h2>{errorMsg}</h2> }else { return ( <div className="row"> { users.map((user,index)=>( <div className="card" key={index}> <a href={user.url} target="_blank"> <img src={user.avatarUrl} style={{width: 100}}/> </a> <p className="card-text">{user.name}</p> </div> )) } </div> ) } } } export default Main
index.css
.album { min-height: 50rem; /* Can be removed; just added for demo purposes */ 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%; }