在React中获取数据
React初學(xué)者經(jīng)常從不需要獲取數(shù)據(jù)的應(yīng)用開始。他們經(jīng)常面臨一個計(jì)數(shù)器,任務(wù)列表獲取井字棋游戲應(yīng)用。這是很好的,因?yàn)樵陂_始學(xué)習(xí)React的時候,數(shù)據(jù)獲取在你的應(yīng)用中添加了另一層復(fù)雜度。
然而,有些時候你想要從自己的或者第三方API請求真實(shí)世界的數(shù)據(jù)。這個文章給你一個怎么在React中獲取數(shù)據(jù)的演練。這沒有外部狀態(tài)管理的解決方案,像Redux或者M(jìn)obX參與存儲你獲取到的數(shù)據(jù)。相反你將要使用React的本地狀態(tài)管理。
內(nèi)容列表
- 在React組件樹的什么位置獲取數(shù)據(jù)?
- 如何在React中獲取數(shù)據(jù)?
- 怎么展示加載標(biāo)識和處理錯誤呢?
- 如何在React中使用Axios獲取數(shù)據(jù)
- 在React怎么測試數(shù)據(jù)獲取?
- 怎么在React中使用Async/Await獲取數(shù)據(jù)?
- 如何在高階組件中獲取數(shù)據(jù)?
- 怎么在渲染屬性里獲取數(shù)據(jù)?
- 在React中怎么從GraphQL獲取數(shù)據(jù)?
在React組件樹的什么位置獲取數(shù)據(jù)?
想象你已經(jīng)有一個組件樹,在它的層級中有多個級別的組件。現(xiàn)在你將要從第三方API獲取一個列表項(xiàng)。現(xiàn)在,在你組件級別的哪個等級,更精確的講,哪個特定組件,應(yīng)該獲取數(shù)據(jù)?這個基本上取決于三個標(biāo)準(zhǔn):
1.誰對這個數(shù)據(jù)感興趣?獲取數(shù)據(jù)的組件應(yīng)該是這些組件的公共父組件。
1. Who is interested in this data? The fetching component should be a common parent component for all these components.
+---------------+| || || || |+------+--------+|+---------+------------+| || |+-------+-------+ +--------+------+| | | || | | || Fetch here! | | || | | |+-------+-------+ +---------------+|+-----------+----------+---------------------+| | || | | +------+--------+ +-------+-------+ +-------+-------+ | | | | | | | | | | | | | I am! | | | | I am! | | | | | | | +---------------+ +-------+-------+ +---------------+||||+-------+-------+| || || I am! || |+---------------+2.當(dāng)異步請求數(shù)據(jù)的時候你想在哪里展示一個加載標(biāo)識(加載標(biāo)志,進(jìn)度條)? 根據(jù)第一個標(biāo)準(zhǔn),這個加載標(biāo)識可以展示在公共父組件中。然后這個公共父組件還是獲取數(shù)據(jù)的組件。
+---------------+| || || || |+------+--------+|+---------+------------+| || |+-------+-------+ +--------+------+| | | || | | || Fetch here! | | || Loading ... | | |+-------+-------+ +---------------+|+-----------+----------+---------------------+| | || | | +------+--------+ +-------+-------+ +-------+-------+ | | | | | | | | | | | | | I am! | | | | I am! | | | | | | | +---------------+ +-------+-------+ +---------------+||||+-------+-------+| || || I am! || |+---------------+**2.1.**但是當(dāng)加載標(biāo)識需要在更高級的組件中,數(shù)據(jù)獲取也需要被提升到這個組件中。
+---------------+| || || Fetch here! || Loading ... |+------+--------+|+---------+------------+| || |+-------+-------+ +--------+------+| | | || | | || | | || | | |+-------+-------+ +---------------+|+-----------+----------+---------------------+| | || | | +------+--------+ +-------+-------+ +-------+-------+ | | | | | | | | | | | | | I am! | | | | I am! | | | | | | | +---------------+ +-------+-------+ +---------------+||||+-------+-------+| || || I am! || |+---------------+2.2. 當(dāng)加載標(biāo)識應(yīng)該在公共父組件的每個子組件展示,不是每個子組件都需要數(shù)據(jù),公共父組件應(yīng)該還是獲取數(shù)據(jù)的組件。然后這個加載標(biāo)識狀態(tài)可以傳下來給那些感興趣,需要展示加載標(biāo)識的子組件。
+---------------+| || || || |+------+--------+|+---------+------------+| || |+-------+-------+ +--------+------+| | | || | | || Fetch here! | | || | | |+-------+-------+ +---------------+|+-----------+----------+---------------------+| | || | | +------+--------+ +-------+-------+ +-------+-------+ | | | | | | | | | | | | | I am! | | | | I am! | | Loading ... | | Loading ... | | Loading ... | +---------------+ +-------+-------+ +---------------+||||+-------+-------+| || || I am! || |+---------------+**3. 當(dāng)請求失敗的時候,你想在哪里展示可選的錯誤信息?**這個和第二個加載標(biāo)識的標(biāo)準(zhǔn)使用一樣的規(guī)則。
這基本上就是在React組件層次結(jié)構(gòu)中獲取數(shù)據(jù)的所有內(nèi)容。但是什么時候獲應(yīng)該取數(shù)據(jù),一旦公共父組件達(dá)成一致應(yīng)該如何獲取數(shù)據(jù)?
如何在React中獲取數(shù)據(jù)?
React的ES6類組件有生命周期方法。render()生命周期方法強(qiáng)制返回一個React元素,因?yàn)楫吘鼓憧赡芟朐谀骋稽c(diǎn)展示獲取到的數(shù)據(jù)。
另一個生命周期方法是獲取數(shù)據(jù)的完美選擇:componentDidMount()。當(dāng)這個方法執(zhí)行的時候,這個組件已經(jīng)通過render()方法渲染了一次,但是將會在獲取數(shù)據(jù)并通過組件的setState()方法將數(shù)據(jù)存儲在本地后再次渲染。之后,本地狀態(tài)可以被render()方法使用去展示,或者通過props向下傳遞。
componentDidMount()生命周期方法是獲取數(shù)據(jù)最好的地方。但是怎么去獲取數(shù)據(jù)? React的生態(tài)系統(tǒng)是一個靈活的框架
從而你可以選擇你自己的方法去獲取數(shù)據(jù)。為了簡單起見,這篇文章將會使用瀏覽器原生fetch API展示它。它使用了JavaScript promise作為異步函數(shù)的結(jié)果。這是獲取數(shù)據(jù)的最小示例,像下面這樣:
import React, { Component } from 'react';class App extends Component {constructor(props) {super(props);this.state = {data: null,};}componentDidMount() {fetch('https://api.mydomain.com').then(response => response.json()).then(data => this.setState({ data }));}... }export default App;這是一個最基本React.js fetch API的例子。這個例子向你展示了在React怎么從API中獲取JSON。然而,這邊文章將要演示怎么從一個真實(shí)世界中第三方API中獲取數(shù)據(jù)。
import React, { Component } from 'react';// ----------------------------------- const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux'; // -----------------------------------class App extends Component {constructor(props) {super(props);this.state = {// -----------------------------------hits: [],// -----------------------------------};}componentDidMount() {// -----------------------------------fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits }));// -----------------------------------}... }export default App;這個例子使用Hacker News API,但是你可以使用你自己的API。當(dāng)數(shù)據(jù)獲取成功,數(shù)據(jù)將通過React的 this.setState()方法被存在本地狀態(tài)中。然后 render方法將再次觸發(fā)并且你可以展示獲取到的數(shù)據(jù)。
...class App extends Component {...render() {const { hits } = this.state;return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);} }export default App;即使render()方法已經(jīng)在 componentDidMount()方法之前執(zhí)行過一次,你不會遇到任何空指針異常,因?yàn)槟阍诒镜貭顟B(tài)里有一個初始的空數(shù)組hits屬性。
**注意:**如果你想知道怎么通過React Hooks特性獲取數(shù)據(jù),查看這個全面的指南如何在ReactHooks中獲取數(shù)據(jù)(翻譯)
怎么展示加載標(biāo)識和處理錯誤呢?
當(dāng)然你需要獲取數(shù)據(jù)到你本地狀態(tài)。但是還有什么?這里還有兩個屬性你可以存儲在狀態(tài)里:加載狀態(tài)和錯誤狀態(tài)。這些將提升你應(yīng)用的用戶體驗(yàn)。
加載狀態(tài)應(yīng)該用于指示一個異步請求在進(jìn)行中。在render()方法之間,由于異步到達(dá),獲取數(shù)據(jù)在等待中。從而你可以在等待期間添加一個加載標(biāo)識。在你獲取數(shù)據(jù)的生命周期方法里,你必須將這個屬性從false切換到true,當(dāng)數(shù)據(jù)被獲取到應(yīng)該從true切換到false。
...class App extends Component {constructor(props) {super(props);this.state = {hits: [],// -----------------------------------isLoading: false,// -----------------------------------};}componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------fetch(API + DEFAULT_QUERY).then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false }));// -----------------------------------}... }export default App;在你的render()方法里你可以使用React的條件渲染去展示加載標(biāo)識或者加載到的數(shù)據(jù)。
...class App extends Component {...render() {// -----------------------------------const { hits, isLoading } = this.state;// -----------------------------------// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}// -----------------------------------return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);} }一個加載標(biāo)識可以向Loading…消息一樣簡單,但是你也可以使用第三方庫區(qū)展示一個標(biāo)識或者待定組件內(nèi)容。你可以通過信號通知用戶數(shù)據(jù)提取正在等待中。
你可以保持在你本地的第二個狀態(tài)將是一個錯誤狀態(tài)。當(dāng)你的應(yīng)用中發(fā)生一個錯誤,沒什么比不給用戶關(guān)于錯誤的標(biāo)識更差的了。
...class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,// -----------------------------------error: null,// -----------------------------------};}...}使用promise的時候經(jīng)常在then()后面使用catch()塊去處理錯誤。這就是為什么可以在原生的fetch API上使用catch()塊。
...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY).then(response => response.json()).then(data => this.setState({ hits: data.hits, isLoading: false }))// -----------------------------------.catch(error => this.setState({ error, isLoading: false }));// -----------------------------------}...}不幸的是,這個原生的fetch API不能使用catch塊捕獲每個錯誤的狀態(tài)碼。例如,當(dāng)一個HTTP 404 發(fā)生了,并不會執(zhí)行到catch塊里。但是當(dāng)你沒有在結(jié)果中匹配到你希望的數(shù)據(jù)時,你可以通過拋出一個錯誤強(qiáng)制執(zhí)行到catch塊。
...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => {if (response.ok) {return response.json();} else {throw new Error('Something went wrong ...');}})// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false })).catch(error => this.setState({ error, isLoading: false }));}...}最后但也很重要的是,你可以再次通過條件渲染在你的render()方法展示一個錯誤消息。
...class App extends Component {...render() {// -----------------------------------const { hits, isLoading, error } = this.state;// -----------------------------------// -----------------------------------if (error) {return <p>{error.message}</p>;}// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);} }這就是使用簡單的React獲取數(shù)據(jù)的基礎(chǔ)知識。你可以閱讀有關(guān)在React的本地狀態(tài)中管理所獲取數(shù)據(jù)的更多信息,或者在React中獨(dú)自管理狀態(tài)諸如Redux之類的庫。
如何在React中使用Axios獲取數(shù)據(jù)
就像已經(jīng)提到的,你可以使用其它庫替代原生的fetch API。例如,另一個庫可能每一個錯誤的請求都會到catch塊中,不需要你自己向原先那樣拋出一個錯誤。一個獲取數(shù)據(jù)好的選擇是axios庫。你可以通過npm install axios在你的項(xiàng)目中安裝axios,然后在你的項(xiàng)目中使用它替代原生的fetch API。讓我們使用axios取代原生的fetch API在React中獲取數(shù)據(jù)重構(gòu)上一個項(xiàng)目。
import React, { Component } from 'react'; // ----------------------------------- import axios from 'axios'; // -----------------------------------const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });// -----------------------------------axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,// -----------------------------------isLoading: false})).catch(error => this.setState({error,isLoading: false}));}... }export default App;就像你看到的,axios也返回了一個JavaScript promise對象。但是現(xiàn)在你不能解決這個promise兩次,因?yàn)閍xios已經(jīng)給你返回了一個JSON響應(yīng)。
此外,當(dāng)使用axios你可以確定所有錯誤都會在catch()塊被捕捉。另外,你需要略微調(diào)整axios返回的數(shù)據(jù)結(jié)構(gòu)就行。
在上一個例子里向你展示了怎么在React的componentDidMount生命周期方法里通過一個HTTP的GET方法獲取數(shù)據(jù)。然而,你也可以通過一個按鈕的點(diǎn)擊來觸發(fā)請求。然后你不需要使用生命周期方法,但是你可以使用自己的類方法。
import React, { Component } from 'react'; import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}// -----------------------------------getStories() {// -----------------------------------this.setState({ isLoading: true });axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}... }export default App;但是這只是React里的GET方法的使用。怎么通過API寫入數(shù)據(jù)?當(dāng)使用axios的時候,你也可以在React發(fā)送一個post請求。你也需要將axios.get()換成axios.post()。
在React怎么測試數(shù)據(jù)獲取?
所以怎么在React組件中測試數(shù)據(jù)獲取呢?這里有一個關(guān)于測試話題的廣泛的React測試教程,當(dāng)你使用create-react-app建立你的應(yīng)用,它已經(jīng)帶來了Jest測試框架和斷言庫。除此之外你也可以使用Mocha(測試框架)和Chai(斷言庫)來實(shí)現(xiàn)這些目的(記住功能會因?yàn)闇y試框架和斷言庫而變化)
當(dāng)測試React組件的時候,在我的測試用例中,我經(jīng)常依賴Enzyme去渲染組件。此外,當(dāng)測試異步數(shù)據(jù)獲取,Sinon有助于檢查和模擬數(shù)據(jù)。
npm install enzyme enzyme-adapter-react-16 sinon --save-dev首先你有你的測試體系,你可以在React腳本中寫你第一個數(shù)據(jù)獲取的測試套件
import React from 'react'; import axios from 'axios';import sinon from 'sinon'; import { mount, configure} from 'enzyme'; import Adapter from 'enzyme-adapter-react-16';import App from './';configure({ adapter: new Adapter() });describe('App', () => {beforeAll(() => {});afterAll(() => {});it('renders data when it fetched data successfully', (done) => {});it('stores data in local state', (done) => {}); });而一個測試用例應(yīng)該在數(shù)據(jù)獲取后在React組件成功渲染數(shù)據(jù),提測測試用例驗(yàn)證數(shù)據(jù)被存儲在本地狀態(tài)里。或許測試兩種情況是冗余的,因?yàn)楫?dāng)數(shù)據(jù)被渲染了,那么數(shù)據(jù)也應(yīng)該被存在本地狀態(tài)里了,但是只是為了展示,你會看到兩個用例。
在所有測試之前,你希望使用模擬數(shù)據(jù)來存儲您的axios請求。你可以為請求創(chuàng)建自己的JavaScript promise 并且之后可以使用它細(xì)膩的控制promise的解決。
...describe('App', () => {const result = {// -----------------------------------data: {hits: [{ objectID: '1', url: 'https://blog.com/hello', title: 'hello', },{ objectID: '2', url: 'https://blog.com/there', title: 'there', },],}};// -----------------------------------const promise = Promise.resolve(result);beforeAll(() => {// -----------------------------------sinon.stub(axios, 'get').withArgs('https://hn.algolia.com/api/v1/search?query=redux').returns(promise);// -----------------------------------});afterAll(() => {// -----------------------------------axios.get.restore();// -----------------------------------});... });在所有測試之后你應(yīng)該再次確認(rèn)移除了所有axios的存根。這句是異步數(shù)據(jù)獲取測試的建立。現(xiàn)在讓我們實(shí)現(xiàn)第一個測試:
...describe('App', () => {...it('stores data in local state', (done) => {const wrapper = mount(<App />);expect(wrapper.state().hits).toEqual([]);promise.then(() => {wrapper.update();expect(wrapper.state().hits).toEqual(result.data.hits);done();});});... });在測試中,你通過Enzyme的mount()函數(shù)開始渲染React組件,這個方法確保所有生命生命周期方法執(zhí)行,并且所有子組件被渲染。
最初你可以在你組件本地狀態(tài)的hit是一個空數(shù)組的時候有一個斷言。這應(yīng)該是正確的,因?yàn)槟阃ㄟ^一個空數(shù)組初始化你的本地狀態(tài)的hits屬性。首先你解決了promise并且手動觸發(fā)了組件的渲染,這個狀態(tài)應(yīng)該在數(shù)據(jù)獲取后改變。
接下來,你可以測試所有內(nèi)容是否相應(yīng)呈現(xiàn)。這個測試和之前測試很像。
...describe('App', () => {...it('renders data when it fetched data successfully', (done) => {const wrapper = mount(<App />);expect(wrapper.find('p').text()).toEqual('Loading ...');promise.then(() => {wrapper.update();expect(wrapper.find('li')).toHaveLength(2);done();});}); });在測試開始前,加載中標(biāo)識應(yīng)該被渲染。再次,一旦你解決了promise并且手動觸發(fā)組件的渲染,應(yīng)該有兩個列表元素用于請求數(shù)據(jù)。
這些基本上就是React中關(guān)于數(shù)據(jù)獲取測試你需要知道的。它不需要復(fù)雜。當(dāng)有自己的promise,你可以精細(xì)控制合適解決promise和更新組件。之后你可以進(jìn)行斷言。之前展示的測試場景只是一個方法。例如,關(guān)于測試工具你不一定需要使用Sinon和Enzyme。
怎么在React中使用Async/Await獲取數(shù)據(jù)?
至今,你只通過通用的方法then()和catch()塊去處理JavaScript promise。使用JavaScript中下一代異步請求怎么樣?讓我們使用async/await重構(gòu)上一個數(shù)據(jù)獲取的例子。
import React, { Component } from 'react'; import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux';class App extends Component {...// -----------------------------------async componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------try {const result = await axios.get(API + DEFAULT_QUERY);// -----------------------------------this.setState({hits: result.data.hits,isLoading: false});// -----------------------------------} catch (error) {// -----------------------------------this.setState({error,isLoading: false});// -----------------------------------}// -----------------------------------}... }export default App;當(dāng)在React中獲取數(shù)據(jù)的時候你可以使用async/await語句取代then()。async語句用于表示函數(shù)是異步執(zhí)行的。它也可以使用在(React)類組件的方法上。await語句是在async函數(shù)內(nèi)部每當(dāng)執(zhí)行異步函數(shù)時使用的。所以在等待的請求解決前下一行是不會執(zhí)行的。此外,如果請求失敗,一個try catch塊可以用于捕獲錯誤。
如何在高階組件中獲取數(shù)據(jù)?
在許多組件中使用它時,之前展示的獲取數(shù)據(jù)的方法可以復(fù)用。一旦一個組件掛載,你想去獲取數(shù)據(jù)并且展示條件加載標(biāo)識和錯誤標(biāo)識。這個組件入境可以分出兩個職責(zé):通過條件渲染展示獲取到的數(shù)據(jù)和獲取到遠(yuǎn)程數(shù)據(jù)之后存在本地狀態(tài)里。而前者只用于渲染目的,后者可以通過高階組件被重用。
注意:當(dāng)你要去閱讀鏈接的文章,你也將會看到你怎么在高階組件中抽象條件渲染。在那之后,你的組件將只關(guān)心展示獲取到的數(shù)據(jù),沒有任何條件渲染。
所以你怎樣引入抽象高階組件處理在React中的數(shù)據(jù)獲取。首先你將會分離所有獲取和存儲邏輯到高階組件中。
const withFetching = (url) => (Component) =>class WithFetching extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return <Component { ...this.props } { ...this.state } />;}}除了渲染,高階組價中每個其他部分都取自上一個組件的數(shù)據(jù)正確提取的部分。另外,高階組件使用接受到的一個url獲取請求數(shù)據(jù)。如果你需要傳遞更多參數(shù)給告誡組件,你也可以擴(kuò)展函數(shù)簽名的參數(shù)列表。
const withFetching = (url, query) => (Comp) =>...另外,告誡組件使用一個名叫data的通過用數(shù)據(jù)包裹本地狀態(tài)。它不再像之前一樣了解具體的屬性名(e.g hits)
第二步,你可以部署所有來自你的App組件的數(shù)據(jù)獲取和狀態(tài)邏輯,因?yàn)樗僖矝]有本地狀態(tài)和生命周期方法。你可以通過函數(shù)式無狀態(tài)組件重用它。傳入的屬性從特定命名改為通用數(shù)據(jù)屬性。
const App = ({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>); }最后但也很重要的是,你可以使用高階組件區(qū)包裹你的App組件。
const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux';...const AppWithFetch = withFetching(API + DEFAULT_QUERY)(App);基本上這就是在React中的抽離數(shù)據(jù)獲取。通過使用告誡組件去獲取數(shù)據(jù),你可以輕松配置任何需要url獲取數(shù)據(jù)的任何組件。另外,你可以擴(kuò)展它通過查詢參數(shù)就像之前展示過得。
#怎么在渲染屬性里獲取數(shù)據(jù)?
在React中可以在高階組件和渲染屬性里二選一。在React中使用渲染屬性去數(shù)據(jù)獲取也是可以的。
class Fetcher extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(this.props.url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return this.props.children(this.state);} }然后你可以再次向下面這樣在你的App組件中使用渲染屬性。
const API = 'https://hn.algolia.com/api/v1/search?query='; const DEFAULT_QUERY = 'redux';...const RenderPropApproach = () =><Fetcher url={API + DEFAULT_QUERY}>{({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}}</Fetcher>通過使用React的children屬性作為渲染蘇醒,你也可以從Fetcher組件傳遞所有本地狀態(tài)。這就是你讓所有條件渲染和最終渲染在你的屬性渲染中的辦法。
在React中怎么從GraphQL獲取數(shù)據(jù)?
最后但也很重要的是,這篇文章應(yīng)該很快提到React的GraphQL API。在React組件中你怎么用使用GraphQL API取代REST API獲取數(shù)據(jù)(如今你使用的是哪個)?基本上它可以以同樣的方式實(shí)現(xiàn),因?yàn)镚raphQL對網(wǎng)絡(luò)層沒有要求。大多數(shù)GraphQL API都是通過HTTP公開的,無論是否使用原生的fetch API還是axios進(jìn)行查詢。如果你感興趣在React中如何通過GraphQL API獲取數(shù)據(jù),前往這篇文章:A complete React with GraphQL Tutorial。
你可以在這個github倉庫找到完成的項(xiàng)目。你還有對于React中數(shù)據(jù)獲取的建議嗎?請聯(lián)系我。你將這篇文章分享給其他學(xué)習(xí)如何在React中獲取數(shù)據(jù)的人對我很有意義。
總結(jié)
以上是生活随笔為你收集整理的在React中获取数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React hook 中的数据获取
- 下一篇: babel6和babel7中关于poly