wake-up-neo.net

Wo kann ich API-Aufrufe mit Hooks in reagieren?

Grundsätzlich führen wir API-Aufrufe in der componentDidMount() Lebenszyklusmethode in React-Klassenkomponenten wie folgt aus

     componentDidMount(){
          //Here we do API call and do setState accordingly
     }

Nachdem Hooks in React v16.7.0 eingeführt wurden, gibt es keine weiteren Klassenkomponenten.

Meine Frage ist, wo genau brauchen wir einen API-Aufruf in Funktionskomponente mit Hooks? 

Haben wir dafür eine ähnliche Methode wie componentDidMount()?

7
Hemadri Dasari

Ja, es gibt einen ähnlichen (aber nicht den gleichen!) Ersatz für componentDidMount mit Hooks, und es ist der useEffect Hook.

Die anderen Antworten beantworten Ihre Frage, wo Sie API-Aufrufe vornehmen können, nicht wirklich. Sie können API-Aufrufe durchführen, indem Sie useEffect und ein leeres Array oder Objekt als zweites Argument als Ersatz für componentDidMount(). Der Schlüssel hier ist das zweite Argument. Wenn Sie kein leeres Array oder Objekt als zweites Argument angeben, wird der API-Aufruf bei jedem Rendern aufgerufen und wird effektiv zu einem componentDidUpdate.

Wie in den Dokumenten erwähnt:

Wenn Sie ein leeres Array [] von Eingaben übergeben, wird React) angezeigt, dass Ihr Effekt nicht von Werten der Komponente abhängt, sodass dieser Effekt nur beim Aktivieren ausgeführt und beim Deaktivieren bereinigt wird. Er hat gewonnen läuft nicht auf Updates.

Hier einige Beispiele für Szenarien, in denen Sie API-Aufrufe durchführen müssen:

API-Aufruf Strictly on Mount

Führen Sie den folgenden Code aus und sehen Sie sich das Ergebnis an.

function User() {
  const [firstName, setFirstName] = React.useState(null);
  const [lastName, setLastName] = React.useState(null);
  
  React.useEffect(() => {
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        const {name} = data.results[0];
        setFirstName(name.first);
        setLastName(name.last);
      });
  }, []); // <-- Have to pass in [] here!

  return (
    <div>
      Name: {!firstName || !lastName ? 'Loading...' : `${firstName} ${lastName}`}
    </div>
  );
}

ReactDOM.render(<User />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

API-Aufruf bei jeder Änderung von Requisiten/Status

Wenn Sie zum Beispiel eine Profilseite eines Benutzers anzeigen, auf der jede Seite eine Benutzer-ID/Eigenschaft hat, sollten Sie diese ID als Wert in den zweiten Parameter von useEffect übergeben, damit die Daten erneut abgerufen werden eine neue Benutzer-ID. componentDidMount ist hier nicht ausreichend, da die Komponente möglicherweise nicht erneut bereitgestellt werden muss, wenn Sie direkt von Benutzer A zum Profil von Benutzer B wechseln.

Auf die traditionelle Art des Unterrichts würden Sie tun:

componentDidMount() {
  this.fetchData();
}

componentDidUpdate(prevProps, prevState) {
  if (prevState.id !== this.state.id) {
    this.fetchData();
  }
}

Mit Haken wäre das:

useEffect(() => {
  this.fetchData();
}, [id]);

Führen Sie den folgenden Code aus und sehen Sie sich das Ergebnis an. Ändern Sie beispielsweise die ID in 2, um zu sehen, dass useEffect erneut ausgeführt wird.

function Todo() {
  const [todo, setTodo] = React.useState(null);
  const [id, setId] = React.useState(1);
  
  React.useEffect(() => {
    if (id == null || id === '') {
      return;
    }
    
    fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
      .then(results => results.json())
      .then(data => {
        setTodo(data);
      });
  }, [id]); // useEffect will trigger whenever id is different.

  return (
    <div>
      <input value={id} onChange={e => setId(e.target.value)}/>
      <br/>
      <pre>{JSON.stringify(todo, null, 2)}</pre>
    </div>
  );
}

ReactDOM.render(<Todo />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

Sie sollten useEffect nachlesen, damit Sie wissen, was Sie damit machen können/nicht können.

Spannung

Wie Dan Abramov am diese GitHub-Ausgabe sagte:

Längerfristig werden wir von diesem (useEffect) Muster abraten, da es die Rennbedingungen fördert. Etwa - zwischen Beginn und Ende Ihres Anrufs könnte alles passieren, und Sie hätten neue Requisiten bekommen können. Stattdessen empfehlen wir Suspense für das Abrufen von Daten

Also bleibt gespannt auf Spannung!

42
Yangshun Tay

Sie können eine Bibliothek verwenden, die die gewünschten Hooks bereitstellt https://resthooks.io

Dann wird das Abrufen Ihrer Daten so einfach wie:

const article = useResource(ArticleResource.detailShape(), { id });

Jetzt haben Sie den Artikel nach ID gepackt. Alle nicht glücklichen Pfade (Laden, Fehlerzustände) werden von Suspense und Fehlergrenzen behandelt.

Befolgen Sie diese einfache Anleitung, um loszulegen: https://resthooks.io/docs/getting-started/installation

Mit nur 7kb gzip sparen Sie viel Schmerz und auf lange Sicht reduzieren Sie Ihre Bündelgröße aufgrund weniger wiederholten Codes.

2

Sie können auch use-http wie:

import useFetch from 'use-http'

function App() {
  // add whatever other options you would add to `fetch` such as headers
  const options = {
    method: 'POST',
    body: {}, // whatever data you want to send
  }

  var [data, loading, error] = useFetch('https://example.com', options)

  // want to use object destructuring? You can do that too
  var { data, loading, error } = useFetch('https://example.com', options)

  if (error) {
    return 'Error!'
  }

  if (loading) {
    return 'Loading!'
  }

  return (
    <code>
      <pre>{data}</pre>
    </code>
  )
}
0
Alex Cory

Wenn Sie Funktionskomponenten mit der Hooks-API verwenden, können Sie die useEffect()-Methode verwenden, um Nebenwirkungen zu erzeugen. Wenn der Status aufgrund dieser Nebenwirkungen aktualisiert wird, wird die Komponente erneut gerendert. 

Beispiel aus den Dokumenten.

import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Sie könnten beispielsweise setCount in einer Rückruffunktion einer asynchronen Anforderung aufrufen. Wenn der Rückruf ausgeführt wird, wird der Status aktualisiert und React rendert die Komponente erneut. Auch aus den Dokumenten:

Tipp

Wenn Sie mit den Lebenszyklusmethoden von React-Klassen vertraut sind, können Sie Folgendes nachdenken. von useEffect Hook als componentDidMount, componentDidUpdate und componentWillUnmount kombiniert.

0
Donny Verduijn