如何在React中做Ajax 請求?
首先:React本身沒有獨有的獲取數據的方式。實際上,就React而言,它甚至不知道有服務器畫面的存在。
React只是簡單地渲染組件,單獨從兩個地方獲取數據:props
和 state
。
因此,為了使用服務器的數據,你需要在你的組件(component)的props或state里拿到數據。
你可以將這個過程與服務和數據模型復雜化,就像你所希望的那樣,但最終只是組件渲染props和state。
選擇一個HTTP 庫
為了獲取來自服務器的數據,你需要一個HTTP
庫,網上有很多,最終他們都做同樣的事情,但他們有不同的特點。
喜歡 Promise?那就選axios吧:https://github.com/mzabriskie...
討厭Promise?,但是喜歡callback?不妨看看superagent?https://github.com/visionmedi...
當然,你也可以選擇自己封裝一個ajax庫,我喜歡Axios,下面將以這個庫作為例子,如果你不喜歡,可以選擇其他庫看看。
Fetch Data
如下是一個簡單的實例,一個組件從subreddit獲取職位。看看這個例子,我們將會了解它是如何工作的
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進來。然后在constructor 里先調用super,接著初始化state,讓它擁有一個posts空數組。componentDidMount是關鍵所在,這個方法將會在組件插入DOM的第一時間執行。該方法在整個組件的生命周期只會執行一次。它使用axios.get方法從subreddit獲取數據,反引號的字符串是ES6的模板字符串,${}部分是由表達式的值所取代,所以URL傳遞給axios.get實際上是http://www.reddit.com/r/react...。
有兩點你需要注意的是:
- 你可以在任意的subreddit URL末尾處附加上.json并且獲得那個職位的json形式的展示
- 如果你忘記www,你會得到一個CORS錯誤
因為Axios使用Promise,所有我們可以鏈式調用then方法來處理response。獲取的職位信息是一點一點的轉換后提取的,最重要的一點是,組件的狀態(state)是由職位與新數組調用this.setState更新的,由此觸發一個重新渲染,然后職位的信息就可以看見了