2017-07-13 6 views
0

Ich versuche zu verstehen, wie ich fetch verwenden kann, um Daten von einer API zu erhalten, und verwenden Sie es zum Erstellen von React-Komponenten. Ich bin ein wenig verwirrt, wenn dies die richtige Methode ist, um die Daten abzurufen, zu speichern und zu verwenden, oder wenn es einen anderen Weg gibt, den ich vielleicht nicht kenne (ich habe etwas in den Dokumenten über Zustände und Reittiere gelesen, aber ich konnte meinen Kopf nicht bekommen) um ihn herum.Datenbereich in Reagieren mit Fetch

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

würde ich mich freuen, wenn Sie mich auf jede Ressource zeigen könnte, dass mir dieses Konzept verstehen helfen können. Vielen Dank im Voraus.

Antwort

1

in Ihr Beispielcode, Sie sind nicht retu Wenn Sie 'resp.json()', resp.json() zurückgeben, wird ein Versprechen zurückgegeben, das Sie zurückgeben müssen, und wenn es erfolgreich verrechnet wird, werden 'Daten' in Ihrem nächsten .then() mit dem Objekt aus dem Verzeichnis gefüllt API-Antwort Möglicherweise möchten Sie dann die Antwortdaten in Ihrem Komponentenstatus festlegen, um etwas zu tun.

habe ich erstellt eine einfache reagieren App mit 'create-reagieren-App' dies demonstrieren:

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. 

Arbeits GitHub Repo hier: https://github.com/finbarrobrien/fetchy/blob/master/src/App.js

+0

Finbarr, du bist ein Gewinner. Ich lade das Projekt herunter und werde bald Fragen stellen. Vielen Dank im Voraus. –

+0

Hallo Finbarr, kannst du mir helfen zu verstehen, was du getan hast? Ich bin ein bisschen unsicher bezüglich einiger Teile des Codes. Hier ist der kommentierte [Gist-Code] (https://gist.github.com/didacus/c674046632f05cf79500de4df9584b7d) –

+0

Ich habe ein neues Commit für die App.js auf meinem Github-Repository als Reaktion auf Ihre Kommentare hinzugefügt. Hoffentlich hilft es, es gibt einige interessante Konzepte zu verstehen/zu lernen wie Cross-Source-Ressourcen-Sharing (CORS), Promises und Javascript-Importe, String-Interpolation und ternäre Ausdrücke. Eine Sache, die ich sagen würde, ist, dass mein Code überhaupt nicht sehr robust ist, und normalerweise würden Sie solch ein Holen in einer reaktiven Komponente nicht machen, stellen Sie sich vor, Sie haben mehrere Komponenten, die dieselben API-Antwortdaten verwenden müssen. Sie hätten ein Abrufmodul, das alle Abrufvorgänge abwickelt, und einen Zustandsspeicher wie z. B. flux/redux –