React 中的 AJAX 請求:獲取數據的方法與時機

lonelygift 8年前發布 | 58K 次閱讀 React Ajax 前端技術

React 新手一開始可能會問到這樣一個問題,“在 React 中如何發送 AJAX 請求呢?”

本文正要回答該問題。

首先:React 本身對獲取數據的方式并無任何特殊偏好。實際上,在 React 的圖景中,根本就不知道“服務器”這種東西的存在。

React 只是使用 propsstate 兩處的數據進行組件渲染。

因此,想要使用來自服務端的數據,必須將數據放入組件的 props 或 state 中。

你完全可以按照喜好使用服務、數據模型(額,“建立抽象”)完成這個過程,但歸根結底只不過是通過 props 和 state 渲染組件。

選擇 HTTP 工具庫

要從服務端拿到數據,首先得有一個 HTTP 工具庫。現成的輪子數都數不清。它們最終做的事情都一樣,但在一些特性上有所不同。

喜歡 Promise?那就試試 axios 吧。

不喜歡 Promise,對回調函數情有獨鐘?可以看一眼 superagent 。

要不試試將要成為標準的一些工具? fetch 可能是你的菜。

這些其實根本不重要。沒有“最佳”工具。

有些人可能會說, fetch 是最好的,因為 fetch 差不多已經是標準了。但我敢打賭,就算fetch 真正 成為標準,還是會有人喜歡、使用一些與之匹敵的 HTTP 工具庫。所以隨你怎么選咯。

我個人比較喜歡 axios ,這也是本文示例所使用的。不過,認真的說,如果你偏偏不喜歡它,那就選其他的唄。

獲取數據

下面是一個簡單的示例組件,它從 Reddit 站點獲取文章列表。先看一眼,后面會講述代碼是如何工作的。

import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';

class FetchDemo extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      posts: []
    };
  }

  componentDidMount() {
    axios.get(`http://www.reddit.com/r/${this.props.subreddit}.json`)
      .then(res => {
        const posts = res.data.data.children.map(obj => obj.data);
        this.setState({ posts });
      });
  }

  render() {
    return (
      <div>
        <h1>{`/r/${this.props.subreddit}`}</h1>
        <ul>
          {this.state.posts.map(post =>
            <li key={post.id}>{post.title}</li>
          )}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(
  <FetchDemo subreddit="reactjs"/>,
  document.getElementById('root')
);

如何工作

首先引入 axios 。

import axios from 'axios';`

constructor 方法非常標準,調用 super ,然后初始化 state,設置一個空的 posts 數組。

真正神奇的事情發生在 componentDidMount 方法中。組件首次“掛載”(mount)時,該方法就會執行。在組件生命周期中,該方法只會執行 一次

TL;DR: 在 componentDidMount 方法中獲取服務端數據

componentDidMount 方法中,根據傳入的 subreddit 屬性,調用 axios.get 方法獲取數據。反引號中是 ES6 模板字符串,可能如你所想, ${...} 部分會被其中表達式的值所替換,因此傳給 axios.get 的 URL 實際上是 http://www.reddit.com/r/reactjs.json 。

此處需注意兩點,和 Reddit 有關:

  • 可以在 Reddit 網站下面所有的 URL 后面添加 .json 后綴,以獲取 JSON 格式的內容。

  • 如果去掉 www ,會產生 CORS 錯誤(至少我碰到了這個錯誤)。

因為 Axios 使用了 Promise,所以可以通過 .then 方法鏈式處理響應。經過一些處理后, posts 被提取出來了,緊接著是重點:

傳入新的 posts 數組,使用 this.setState 方法更新組件狀態。這會導致重新渲染,接下來文章列表就顯示出來了。

這就是所有的一切啦哈哈!

額外獎勵:添加加載指示

知道怎樣修改代碼,在請求尚未返回時添加一個 "Loading..." 消息嗎?

提示:在 state 中設置一個標志,一旦請求完成則將其切換其值。在 render 函數中使用這個標志顯示加載提示。

如果想看示例代碼(包括加載提示以及附加的 error state ),可以點擊 這里 下載可運行的例子,無需注冊喲~

解壓文件,依次執行 npm install 和 npm start 。示例基于棒棒噠 Create React App 創建。

 

來自:http://www.zcfy.cc/article/ajax-requests-in-react-how-and-where-to-fetch-data-1348.html

 

 本文由用戶 lonelygift 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!