Wenn Sie neu in React sind und vielleicht nur To-Do- und Zähler-Apps erstellt haben, sind Sie möglicherweise noch nicht auf die Notwendigkeit gestoßen, Daten für Ihre App abzurufen. Wahrscheinlich wird es eine Zeit geben, in der Sie dies tun müssen, da React-Apps am besten für Situationen geeignet sind, in denen Sie sowohl Daten als auch Zustände verwalten. gut geeignet
Die erste Datenmenge, die Sie möglicherweise verarbeiten müssen, könnte fest in Ihrer React-Anwendung codiert sein, wie wir es für diese Demo aus unserem Error-Boundary-Tutorial getan haben
Sehen Sie den Pen error boundary 0 von Kingsley Silas Chijioke (@kinsomicrote) auf CodePen.
Was ist, wenn Sie Daten von einer API verwalten möchten? Das ist der Zweck dieses Tutorials. Insbesondere werden wir die Fetch API und axios als Beispiele für die Anforderung und Nutzung von Daten verwenden.
Die Fetch API
Die Fetch API bietet eine Schnittstelle zum Abrufen von Ressourcen. Wir werden sie verwenden, um Daten von einer Drittanbieter-API abzurufen und zu sehen, wie wir sie beim Abrufen von Daten von einer intern entwickelten API verwenden können.
Fetch mit einer Drittanbieter-API verwenden
Sehen Sie den Pen React Fetch API Pen 1 von Kingsley Silas Chijioke (@kinsomicrote) auf CodePen.
Wir werden zufällige Benutzer von JSONPlaceholder abrufen, einer gefälschten Online-REST-API zum Testen. Beginnen wir mit der Erstellung unserer Komponente und der Deklaration einiger Standardzustände.
class App extends React.Component {
state = {
isLoading: true,
users: [],
error: null
}
render() {
<React.Fragment>
</React.Fragment>
}
}
Beim Anfordern von Daten über das Netzwerk wird es zwangsläufig zu Verzögerungen kommen. Es könnten einige Sekunden oder vielleicht einige Millisekunden sein. In jedem Fall ist es während dieser Verzögerung eine gute Praxis, die Benutzer darüber zu informieren, dass während der Verarbeitung der Anfrage etwas geschieht.
Dazu werden wir isLoading verwenden, um entweder die Ladeanzeige *oder* die angeforderten Daten anzuzeigen. Die Daten werden angezeigt, wenn isLoading auf false gesetzt ist, andernfalls wird eine Ladeanzeige auf dem Bildschirm angezeigt. Die render()-Methode sieht also so aus
render() {
const { isLoading, users, error } = this.state;
return (
<React.Fragment>
<h1>Random User</h1>
// Display a message if we encounter an error
{error ? <p>{error.message}</p> : null}
// Here's our data check
{!isLoading ? (
users.map(user => {
const { username, name, email } = user;
return (
<div key={username}>
<p>Name: {name}</p>
<p>Email Address: {email}</p>
<hr />
</div>
);
})
// If there is a delay in data, let's let the user know it's loading
) : (
<h3>Loading...</h3>
)}
</React.Fragment>
);
}
Der Code macht im Grunde Folgendes
- Entpackt
isLoading,usersunderroraus dem Anwendungszustand, damit wir nicht ständigthis.stateeingeben müssen. - Gibt eine Meldung aus, wenn die Anwendung beim Aufbau einer Verbindung einen Fehler hat
- Prüft, ob Daten geladen werden
- Wenn das Laden nicht stattfindet, müssen wir die Daten haben, also zeigen wir sie an
- Wenn geladen wird, müssen wir noch daran arbeiten und "Laden..." anzeigen, während die App arbeitet
Damit die Schritte 3-5 funktionieren, müssen wir die Anfrage zum Abrufen von Daten von einer API stellen. Hier kommt die JSONplaceholder-API für unser Beispiel ins Spiel.
fetchUsers() {
// Where we're fetching data from
fetch(`https://jsonplaceholder.typicode.com/users`)
// We get the API response and receive data in JSON format...
.then(response => response.json())
// ...then we update the users state
.then(data =>
this.setState({
users: data,
isLoading: false,
})
)
// Catch any errors we hit and update the app
.catch(error => this.setState({ error, isLoading: false }));
}
Wir erstellen eine Methode namens fetchUser() und verwenden sie, um genau das zu tun, was Sie vielleicht denken: Benutzerdaten von dem API-Endpunkt anfordern und für unsere App abrufen. Fetch ist eine Promise-basierte API, die ein Antwortobjekt zurückgibt. Wir verwenden also die json()-Methode, um das Antwortobjekt zu erhalten, das in data gespeichert und zur Aktualisierung des Zustands der Benutzer in unserer Anwendung verwendet wird. Wir müssen auch den Zustand von isLoading auf false ändern, damit unsere Anwendung weiß, dass das Laden abgeschlossen ist und alles für die Anzeige der Daten bereit ist.
Da Fetch Promise-basiert ist, können wir Fehler auch mit der .catch()-Methode abfangen. Jeder aufgetretene Fehler wird als Wert verwendet, um unseren Fehlerzustand zu aktualisieren. Praktisch!
Beim ersten Rendern der Anwendung wurden die Daten noch nicht empfangen – das kann Sekunden dauern. Wir möchten die Methode zum Abrufen der Benutzer auslösen, wenn auf den Anwendungszustand für eine Aktualisierung zugegriffen werden kann und die Anwendung neu gerendert wird. Reacts componentDidMount() ist der beste Ort dafür, also platzieren wir die fetchUsers()-Methode dort.
componentDidMount() {
this.fetchUsers();
}
Fetch mit eigener API verwenden
Bisher haben wir uns angesehen, wie die Daten anderer Personen in einer Anwendung verwendet werden können. Aber was ist, wenn wir mit unseren eigenen Daten in unserer eigenen API arbeiten? Das werden wir jetzt behandeln.
Sehen Sie den Pen React Fetch API Pen 2 von Kingsley Silas Chijioke (@kinsomicrote) auf CodePen.
Ich habe eine API entwickelt, die auf GitHub verfügbar ist. Die JSON-Antwort, die Sie erhalten, wurde auf AWS platziert – das werden wir für dieses Tutorial verwenden.
Wie zuvor erstellen wir unsere Komponente und richten einige Standardzustände ein.
class App extends React.Component {
state = {
isLoading: true,
posts: [],
error: null
}
render() {
<React.Fragment>
</React.Fragment>
}
}
Unsere Methode zum Durchlaufen der Daten wird sich von der zuvor verwendeten unterscheiden, aber nur wegen der Datenstruktur, die anders sein wird. Sie können den Unterschied zwischen unserer Datenstruktur hier und der von JSONPlaceholder erhaltenen sehen.
Hier sieht die render()-Methode für unsere API aus
render() {
const { isLoading, posts, error } = this.state;
return (
<React.Fragment>
<h1>React Fetch - Blog</h1>
<hr />
{!isLoading ? Object.keys(posts).map(key => <Post key={key} body={posts[key]} />) : <h3>Loading...</h3>}
</React.Fragment>
);
}
Lassen Sie uns die Logik aufschlüsseln
{
!isLoading ?
Object.keys(posts).map(key => <Post key={key} body={posts[key]} />)
: <h3>Loading...</h3>
}
Wenn isLoading nicht true ist, geben wir ein Array zurück, mappen es und übergeben die Informationen als Props an die Post-Komponente. Andernfalls zeigen wir eine "Laden..."-Meldung an, während die Anwendung arbeitet. Sehr ähnlich wie zuvor.
Die Methode zum Abrufen von Beiträgen sieht so aus wie im ersten Teil verwendet.
fetchPosts() {
// The API where we're fetching data from
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json`)
// We get a response and receive the data in JSON format...
.then(response => response.json())
// ...then we update the state of our application
.then(
data =>
this.setState({
posts: data,
isLoading: false,
})
)
// If we catch errors instead of a response, let's update the app
.catch(error => this.setState({ error, isLoading: false }));
}
Jetzt können wir die Methode fetchPosts in einer componentDidMount()-Methode aufrufen
componentDidMount() {
this.fetchPosts();
}
In der Post-Komponente mappen wir durch die erhaltenen Props und rendern den Titel und Inhalt für jeden Beitrag
const Post = ({ body }) => {
return (
<div>
{body.map(post => {
const { _id, title, content } = post;
return (
<div key={_id}>
<h2>{title}</h2>
<p>{content}</p>
<hr />
</div>
);
})}
</div>
);
};
Da haben wir es! Jetzt wissen wir, wie man die Fetch API verwendet, um Daten aus verschiedenen Quellen abzurufen und in einer Anwendung zu nutzen. Hohe fünf. ✋
axios
Okay, wir haben viel Zeit mit der Fetch API verbracht und wenden uns nun axios zu.
Wie die Fetch API ist axios eine Möglichkeit, Daten für unsere Anwendung anzufordern. Wo axios glänzt, ist, wie es Ihnen ermöglicht, eine asynchrone Anfrage an REST-Endpunkte zu senden. Dies ist nützlich, wenn Sie mit der REST-API in einem React-Projekt arbeiten, z. B. einem headless WordPress CMS.
Es gibt eine anhaltende Debatte darüber, ob Fetch besser ist als axios und umgekehrt. Wir werden hier nicht darauf eingehen, denn nun ja, Sie können das richtige Werkzeug für den richtigen Job auswählen. Wenn Sie neugierig auf die Argumente jeder Seite sind, können Sie hier und hier nachlesen.
Axios mit einer Drittanbieter-API verwenden
Sehen Sie den Pen React Axios 1 Pen von Kingsley Silas Chijioke (@kinsomicrote) auf CodePen.
Wie wir es mit der Fetch API getan haben, beginnen wir mit der Anforderung von Daten von einer API. Für diese werden wir zufällige Benutzer von der Random User API abrufen.
Zuerst erstellen wir die App-Komponente, wie wir es jedes Mal zuvor getan haben
class App extends React.Component {
state = {
users: [],
isLoading: true,
errors: null
};
render() {
return (
<React.Fragment>
</React.Fragment>
);
}
}
Die Idee ist immer noch die gleiche: Prüfen Sie, ob das Laden im Gange ist, und rendern Sie entweder die Daten, die wir zurückbekommen, oder informieren Sie den Benutzer, dass die Dinge noch geladen werden.
Um die Anfrage an die API zu stellen, müssen wir eine Funktion erstellen. Wir nennen die Funktion getUsers(). Darin werden wir die Anfrage an die API mit axios stellen. Sehen wir uns das an, bevor wir weiter erklären.
getUsers() {
// We're using axios instead of Fetch
axios
// The API we're requesting data from
.get("https://randomuser.me/api/?results=5")
// Once we get a response, we'll map the API endpoints to our props
.then(response =>
response.data.results.map(user => ({
name: `${user.name.first} ${user.name.last}`,
username: `${user.login.username}`,
email: `${user.email}`,
image: `${user.picture.thumbnail}`
}))
)
// Let's make sure to change the loading state to display the data
.then(users => {
this.setState({
users,
isLoading: false
});
})
// We can still use the `.catch()` method since axios is promise-based
.catch(error => this.setState({ error, isLoading: false }));
}
Ziemlich anders als die Fetch-Beispiele, oder? Die Grundstruktur ist eigentlich recht ähnlich, aber jetzt beschäftigen wir uns mit dem Mapping von Daten zwischen Endpunkten.
Die GET-Anfrage wird als Parameter von der API-URL übergeben. Die Antwort, die wir von der API erhalten, enthält ein Objekt namens data, und dieses enthält weitere Objekte. Die gewünschten Informationen sind in data.results verfügbar, was ein Array von Objekten ist, die die Daten einzelner Benutzer enthalten.
Hier sind wir wieder, indem wir unsere Methode in der componentDidMount()-Methode aufrufen
componentDidMount() {
this.getUsers();
}
Alternativ können Sie dies tun und im Grunde diese ersten beiden Schritte kombinieren
componentDidMount() {
axios
.get("https://randomuser.me/api/?results=5")
.then(response =>
response.data.results.map(user => ({
name: `${user.name.first} ${user.name.last}`,
username: `${user.login.username}`,
email: `${user.email}`,
image: `${user.picture.thumbnail}`
}))
)
.then(users => {
this.setState({
users,
isLoading: false
});
})
.catch(error => this.setState({ error, isLoading: false }));
}
Wenn Sie lokal von Ihrem Rechner aus programmieren, können Sie die Funktion getUsers() vorübergehend wie folgt bearbeiten
getUsers() {
axios
.get("https://randomuser.me/api/?results=5")
.then(response => console.log(response))
.catch(error => this.setState({ error, isLoading: false }));
}
Ihre Konsole sollte etwas Ähnliches wie das hier erhalten

Wir mappen durch das Ergebnisse-Array, um die benötigten Informationen für jeden Benutzer zu erhalten. Das Array von Benutzern wird dann verwendet, um einen neuen Wert für unseren users-Zustand festzulegen. Danach können wir den Wert von isLoading ändern.
Standardmäßig ist isLoading auf true gesetzt. Wenn der Zustand von users aktualisiert wird, möchten wir den Wert von isLoading auf false ändern, da dies das Signal ist, auf das unsere App wartet, um von "Laden..." zu gerenderten Daten zu wechseln.
render() {
const { isLoading, users } = this.state;
return (
<React.Fragment>
<h2>Random User</h2>
<div>
{!isLoading ? (
users.map(user => {
const { username, name, email, image } = user;
return (
<div key={username}>
<p>{name}</p>
<div>
<img src={image} alt={name} />
</div>
<p>{email}</p>
<hr />
</div>
);
})
) : (
<p>Loading...</p>
)}
</div>
</React.Fragment>
);
}
Wenn Sie den users-Zustand in der Konsole protokollieren, sehen Sie, dass es sich um ein Array von Objekten handelt

Das leere Array zeigt den Wert vor dem Abruf der Daten an. Die zurückgegebenen Daten enthalten nur den Namen, den Benutzernamen, die E-Mail-Adresse und das Bild einzelner Benutzer, da dies die Endpunkte sind, die wir zugeordnet haben. Es gibt natürlich noch viele weitere Daten von der API, aber wir müssten diese zu unserer getUsers-Methode hinzufügen.
Axios mit eigener API verwenden
Sehen Sie den Pen React Axios 2 Pen von Kingsley Silas Chijioke (@kinsomicrote) auf CodePen.
Sie haben gesehen, wie man axios mit einer Drittanbieter-API verwendet, aber wir können uns ansehen, wie es ist, Daten von unserer eigenen API abzurufen, genau wie wir es mit der Fetch API getan haben. Tatsächlich verwenden wir dieselbe JSON-Datei, die wir für Fetch verwendet haben, damit wir den Unterschied zwischen den beiden Ansätzen sehen können.
Hier ist alles zusammengefasst
class App extends React.Component {
// State will apply to the posts object which is set to loading by default
state = {
posts: [],
isLoading: true,
errors: null
};
// Now we're going to make a request for data using axios
getPosts() {
axios
// This is where the data is hosted
.get("https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json")
// Once we get a response and store data, let's change the loading state
.then(response => {
this.setState({
posts: response.data.posts,
isLoading: false
});
})
// If we catch any errors connecting, let's update accordingly
.catch(error => this.setState({ error, isLoading: false }));
}
// Let's our app know we're ready to render the data
componentDidMount() {
this.getPosts();
}
// Putting that data to use
render() {
const { isLoading, posts } = this.state;
return (
<React.Fragment>
<h2>Random Post</h2>
<div>
{!isLoading ? (
posts.map(post => {
const { _id, title, content } = post;
return (
<div key={_id}>
<h2>{title}</h2>
<p>{content}</p>
<hr />
</div>
);
})
) : (
<p>Loading...</p>
)}
</div>
</React.Fragment>
);
}
}
Der Hauptunterschied zwischen dieser Methode und der Verwendung von axios zum Abrufen von Daten von einem Drittanbieter liegt in der Formatierung der Daten. Wir erhalten hier direkt JSON und nicht durch das Mapping von Endpunkten.
Die Posts-Daten, die wir von der API erhalten, werden verwendet, um den Wert des posts-Zustands der Komponente zu aktualisieren. Damit können wir in render() durch das Array der Posts mappen. Wir erhalten dann die id, den Titel und den Inhalt jedes Posts mithilfe von ES6-Destrukturierung, die dann dem Benutzer angezeigt wird.
Wie wir zuvor gemacht haben, hängt das, was angezeigt wird, vom Wert von isLoading ab. Als wir einen neuen Zustand für posts mit den von der API erhaltenen Daten gesetzt haben, mussten wir auch einen neuen Zustand für isLoading setzen. Dann können wir dem Benutzer endlich mitteilen, dass Daten geladen werden, oder die erhaltenen Daten rendern.
async und await
Eine weitere Sache, die die Promise-basierte Natur von axios uns ermöglicht, ist die Nutzung von async und await. Damit sieht die Funktion getPosts() so aus.
async getPosts() {
const response = await axios.get("https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json");
try {
this.setState({
posts: response.data.posts,
isLoading: false
});
} catch (error) {
this.setState({ error, isLoading: false });
}
}
Basis-Instanz
Mit axios ist es möglich, eine Basisinstanz zu erstellen, in der wir die URL für unsere API wie folgt einfügen
const api = axios.create({
baseURL: "https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json"
});
…und sie dann so verwenden
async getPosts() {
const response = await api.get();
try {
this.setState({
posts: response.data.posts,
isLoading: false
});
} catch (error) {
this.setState({ error, isLoading: false });
}
}
Einfach eine nette Möglichkeit, die API-URL zu abstrahieren.
Jetzt, Daten für alles!
Während Sie React-Anwendungen erstellen, werden Sie auf viele Szenarien stoßen, in denen Sie Daten von einer API verwalten möchten. Hoffentlich fühlen Sie sich jetzt gerüstet und bereit, Daten aus einer Vielzahl von Quellen mit Optionen für die Anforderung zu verarbeiten.
Möchten Sie mit mehr Daten spielen? Sarah hat kürzlich die Schritte zum Erstellen Ihrer eigenen serverlosen API aus einer Liste öffentlicher APIs aufgeschrieben.
Schönes Tutorial!!! Übrigens, im Async-Beispiel sollte await innerhalb des try-Blocks stehen.
Danke, Viral, ich werde es mir ansehen.
Ich weiß nicht viel über Fetch, aber ich glaube nicht, dass es Dinge wie Request- und Response-Interceptors tun kann, die bei Dingen wie der Autorisierung all Ihrer Anfragen von unschätzbarem Wert sein können. Fetch hat den Vorteil, dass es nativ ist, also keine zusätzliche Bibliothek zum Laden, aber es ist anscheinend viel einfacher.
Warum prüfen Sie
!isLoading-> "Daten anzeigen" : "Laden anzeigen". Warum nicht umgekehrt, um den Code natürlicher zu lesen:isLoading-> "Laden anzeigen" : "Daten anzeigen"?Danke dafür. Ich kann die Fehlermeldung
error.messagenicht anzeigen lassen, wenn ich zum Beispiel die Fetch-Adresse absichtlich falsch angebe?