使用 Fetch 在 React 中的数据范围

data scope in React using Fetch

我想了解如何使用 fetch 从 API 获取数据并使用它来创建 React 组件。如果这是检索、存储和使用数据的正确方法,或者是否有另一种我可能不知道的方法,我有点困惑(我在文档中阅读了一些关于状态和安装的内容,但我无法理解周围。

JS

//Data
const url = 'https://api.tfl.gov.uk/BikePoint'; // API

fetch(url)
.then((resp) => resp.json()) // Transform the data into json
.then(function(data) {
  // How can I make data accessible outside this function?
 })

.catch(function(error) {
  console.log(JSON.stringify(error));
});

//React
const List = ({items, each}) =>

  <div className = "panel panel-default">
  <div className = "panel-heading"><h2>Bike points</h2></div>
    <div className = "panel-body">   

      <ul className = "list-group">{items.map((item, key) =>
        <ListItem key = {key} item = {each(item)} number={item.commonName}/>)}</ul>

    </div>
  </div>

const ListItem = ({item, arrival, number}) =>
  <li className = "list-group-item">{number}</li>

//How can access the data here?
ReactDOM.render(<List items={data} each={ListItem} />, document.querySelector('#main'))

CodePen

如果您能指出任何可以帮助我理解这个概念的资源,我将不胜感激。提前谢谢你。

在您的示例代码中,您没有 returning 'resp.json()',resp.json() 将 return 一个承诺,您需要 return 如果它成功解析,那么下一个 .then() 中的 'data' 将填充 API 响应中的对象。然后,您可能希望在组件状态中设置响应数据以执行某些操作。

我用 'create-react-app' 创建了一个简单的 React 应用来演示:

import React, { Component } from 'react'; //import 'React' default export, and { Component } non-default export from react
import fetch from 'isomorphic-fetch'; // isomorphic-fetch is used for both server side and client side 'fetch' (see https://github.com/matthew-andrews/isomorphic-fetch)
// App.css was a hangover from the create-react-app, it's not really needed for this basic example
const url = 'https://api.tfl.gov.uk/BikePoint'; // API




class App extends Component { // This is the same as 'extends 'React.Component'

    constructor(props) {
        super(props);
        this.state = {
            fetchedData: null // stores the result of the fetch response body converted to a javascript object
        };
    }

  fetchIt = () => {
      console.log('fetching it');
      fetch(url, { mode: 'cors' }) // Make sure fetch is cross-origin, it's not by default (see https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) since the target URL of the API is a different 'origin' to our react app
          .then((resp) => {
            console.log(resp);
          return resp.json(); })
          .then((data) => { // data input parameter is the result of the resolved resp.json() Promise (see https://developer.mozilla.org/en-US/docs/Web/API/Body/json)
              console.log(data);
              this.setState({ fetchedData: data }); // setState sets the component state with the data from the API response
          })
          .catch(function(error) {
              console.log(JSON.stringify(error));
          });
  }



  render() {
      if(!this.state.fetchedData){ // only do the fetch if there is no fetchedData already (BTW this will run many times if the API is unavailable, or 'fetchIt() encounters an error)
          this.fetchIt();
      }

    return (
      <div>
          {
              this.state.fetchedData ? `fetched ${this.state.fetchedData.length} entries`  : 'no data' // This is a 'ternary' expression, a simple 'if->else'
              /* equivalent to:

                if(this.state.fetchedData) {
                    return `fetched ${this.state.fetchedData.length} entries`; // this is 'javascript string interpolation'
                } else {
                    return 'no data';
                }
              *
              * */
          }
      </div>
    );
  }
}

export default App; // Export our component to be used by other react higher order components (parents), in this case, it's imported in 'index.js', data is only fetched when the component renders.

在此处工作 github 回购:https://github.com/finbarrobrien/fetchy/blob/master/src/App.js