React学习【04】React Ajax的使用

React Ajax的使用

1. React Ajax

  • React本身只关注于界面, 并不包含发送ajax请求的代码
  • 前端应用需要通过ajax请求与后台进行交互(json数据)
  • react应用中需要集成第三方ajax库(或自己封装)

2. 常用的Ajax请求库

  • jQuery: 比较重, 如果需要另外引入不建议使用
  • axios: 轻量级, 建议使用
    • 封装XmlHttpRequest对象的ajax
    • promise风格
    • 可以用在浏览器端和node服务器端
  • fetch: 原生函数, 但老版本浏览器不支持
    • 不再使用XmlHttpRequest对象提交ajax请求
    • 为了兼容低版本的浏览器, 可以引入兼容库fetch.js

3. axios

文档https://github.com/axios/axios

  • get
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

  • post
axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
})
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});

例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script type="text/javascript" src="./js/react.development.js"></script>
  <script type="text/javascript" src="./js/react-dom.development.js"></script>
  <script type="text/javascript" src="./js/prop-types.js"></script>
  <script type="text/javascript" src="./js/babel.min.js"></script>
  <script type="text/javascript" src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
  /*
  需求:
    1. 界面效果如下
    2. 根据指定的关键字在github上搜索匹配的最受关注的库
    3. 显示库名, 点击链接查看库
    4. 测试接口: https://api.github.com/search/repositories?q=r&sort=stars
  */
  axios.get("https://api.github.com/search/repositories?q=r&sort=stars")
    .then(response => {
      console.log(response.data);
    })
    .catch(error => {
      alert(error.message)
    })
</script>
</body>
</html>

4. fetch

文档

https://github.github.io/fetch/

https://segmentfault.com/a/1190000003810652

  • get
fetch(url).then(function(response) {
  return response.json()
}).then(function(data) {
  console.log(data)
}).catch(function(e) {
  console.log(e)
});
  • post
fetch(url, {
  method: "POST",
  body: JSON.stringify(data),
}).then(function(data) {
  console.log(data)
}).catch(function(e) {
  console.log(e)
})

例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script type="text/javascript" src="./js/react.development.js"></script>
  <script type="text/javascript" src="./js/react-dom.development.js"></script>
  <script type="text/javascript" src="./js/prop-types.js"></script>
  <script type="text/javascript" src="./js/babel.min.js"></script>
</head>
<body>

<script type="text/babel">
  fetch('https://api.github.com/search/repositories?q=r&sort=stars', {method: "GET"})
  //固定写法
    .then(
    response => response.json()
  )
  //获取数据
  .then(data => {
    console.log(data)
    //判断是否出错
    if(data.message) {
      alert(`请求失败: ${data.message}`)
    } else {
      const repo = data.items[0]
      alert(JSON.stringify(repo))
    }
  })
</script>
</body>
</html>

5. 综合案例

5.1 案例1

需求:

  1. 界面效果如下

  2. 根据指定的关键字在github上搜索匹配的最受关注的库

  3. 显示库名, 点击链接查看库

  4. 测试接口: https://api.github.com/search/repositories?q=r&sort=stars

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script type="text/javascript" src="./js/react.development.js"></script>
  <script type="text/javascript" src="./js/react-dom.development.js"></script>
  <script type="text/javascript" src="./js/prop-types.js"></script>
  <script type="text/javascript" src="./js/babel.min.js"></script>
  <script type="text/javascript" src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">

  class App extends React.Component {

    state = {
      name : '',
      url : ''
    }

    componentDidMount(){
      const {name} = this.props;
      axios.get("https://api.github.com/search/repositories?q=" + name + "&sort=stars")
        .then(response => {
          const repo = response.data.items[0]
          console.log(repo);
          this.setState({
            name:repo.name,
            url:repo.html_url
          })
        })
        .catch(error => {
          alert("请求失败," + error.message)
        })
    }

    render() {
      const {name,url} = this.state
      if(!name) {
        return <h2>loading...</h2>
      } else {
        return (
          <h2>
            most star repo is <a href={url}>{name}</a>
          </h2>
        )
      }
     }
  }

  ReactDOM.render(<App name="react"/>, document.getElementById('example'));
</script>
</body>
</html>

结果:

在这里插入图片描述

5.1 案例2

案例地址 : react-learn-demo/class_02/class-demo-04-github

5.1.1 组件拆分

在这里插入图片描述

5.1.2 基本步骤

  1. 编写静态组件
  2. 实现动态数据

5.1.3 环境安装

npm install axios
npm install prop-types

5.1.4 基本结构

在这里插入图片描述

5.1.5 具体代码

5.1.5.1 index.js
import React,{Component} from 'react'
import ReactDOM from 'react-dom'

import './index.css'
import App from './components/app'

ReactDOM.render(<App />, document.getElementById('root'));
5.1.5.2 app.jsx
import React, {Component} from 'react'

import Search from './search'
import List from "./list";

export default class App extends Component {

  state = {
    searchName: ''
  }

  setSearchName = (name) => {
    this.setState({
      searchName: name
    })
  }

  render() {
    return (
      <div>
        <div id="app">
          <div className="container">
            <Search setSearchName={this.setSearchName}/>
            <List searchName={this.state.searchName}/>
          </div>
        </div>
      </div>
    )
  }
}

5.1.5.3 search.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types'

export default class Search extends Component {

  static propTypes = {
    setSearchName: PropTypes.func.isRequired
  }

  submitSearchName = () => {
    const inputValue = this.input.value;
    this.props.setSearchName(inputValue)
  }

  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.submitSearchName}>Search</button>
        </div>
      </section>
    )
  }
}

5.1.5.4 list.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'

import Card from './card'

export default class List extends Component {

  state = {
    firstView: true,
    loading: false,
    users: [],
    error: null
  }

  static propTypes = {
    searchName:PropTypes.string.isRequired
  }

  async componentWillReceiveProps(nextProps){
    const {searchName} = nextProps
    //正在加载
    this.setState({
      firstView : false,
      loading : true
    })
    //发送请求
    axios.get("https://api.github.com/search/repositories?q=" + searchName + "&sort=stars")
      .then(response => {
        this.setState({
          loading : false,
          users : response.data.items
        })
      })
      .catch(error => {
        console.log(error.message);
        this.setState({
          loading : false,
          error : error.message
        })
      })
  }

  render() {
    if (this.state.firstView) {
      return <h2>Enter name to search</h2>
    } else if (this.state.loading) {
      return <h2>Loading result...</h2>
    } else if (this.state.error) {
      return <h2>{this.state.error}</h2>
    } else {
      return (
        <div className="row">
          {
            this.state.users.map((user,index) => (
              <Card user={user} key={index}/>
            ))
          }
        </div>
      )
    }
  }
}

5.1.5.5 card.jsx
import React, {Component} from 'react'
import PropTypes from 'prop-types'

export default class Card extends Component {

  static propTypes = {
    user:PropTypes.object.isRequired
  }

  render() {
    const {user} = this.props
    return (
      <div className="card" key={user.html_url}>
        <a href={user.html_url} target="_blank">
          <img src={user.owner.avatar_url} style={{width: '100px'}} alt='user'/>
        </a>
        <p className="card-text">{user.name}</p>
      </div>
    )
  }
}
5.1.5.6 运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值