Dies ist eine einfache Frage. Wie aktualisiere ich das Statusobjekt erfolgreich über React Hooks?

Ich habe gerade angefangen, Hooks zu verwenden, und ich mag, wie es die einfache und reine JavaScript-Funktion ermöglicht, mit der Funktion useState() einen Status zu erstellen und zu verwalten und mit der Funktion useEffect() Änderungen vorzunehmen, die sich auf Komponenten auswirken , aber ich kann anscheinend keine Aktualisierung des Zustands vornehmen!

Nachdem eine Anforderung an eine API gestellt wurde, werden die erforderlichen Daten zurückgegeben. Wenn ich jedoch versuche, den Status für einen Fehler in der Anforderung und für eine erfolgreiche Anforderung zu aktualisieren, wird der Status nicht aktualisiert. Ich habe es in der Browserkonsole protokolliert, aber es wurde keine Änderung am Status vorgenommen. Es wird undefiniert zurückgegeben.

enter image description here

Ich weiß, dass ich im Code etwas nicht richtig mache. Hier ist meine App -Komponente. Es ist eine einzelne Komponente zum Abrufen und Aktualisieren:

import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';


export default function App() {

    // Set date state
    const [data,setData]  = useState({
       data: [],
       loaded: false,
       placeholder: 'Loading' 
    });

    // Fetch and update date
    useEffect(() => {

        fetch('http://localhost:8000/api/lead/')
        .then(response => {
            if (response.status !== 200) {
                SetData({placeholder: 'Something went wrong'});
            }
            response.json()
        })
        .then(result => {
           console.log(data);
           setData({data: result});
        });

    },[]);

    return (
      <h1>{console.log(data)}</h1>
    );
}

ReactDOM.render(<App />, document.getElementById('app'));
2
Romeo 19 Feb. 2020 im 20:09

3 Antworten

Beste Antwort

Es gibt einige Dinge, die Sie verbessern können:

  • Der React-Hook useState verhält sich nicht wie das Klassengegenstück. Das bereitgestellte Objekt wird nicht automatisch mit dem Status zusammengeführt. Sie müssen dies selbst tun.
  • Ich würde empfehlen, wenn Sie ohne ein Objekt als Status arbeiten können, da dies die Anzahl der erneuten Rendern um einen erheblichen Betrag reduzieren und es einfacher machen kann, die Form des Status anschließend zu ändern, da Sie einfach Variablen hinzufügen oder entfernen können und sehen Sie alle Verwendungen sofort.

Mit einem Zustandsobjekt

export default function App() {

    // Set date state
    const [data,setData]  = useState({
       data: [],
       loaded: false,
       placeholder: 'Loading' 
    });

    // Fetch and update date
    useEffect(() => {
        fetch('http://localhost:8000/api/lead/')
        .then(response => {
            if (response.status !== 200) {
                throw new Error(response.statusText); // Goto catch block
            }
            return response.json(); // <<- Return the JSON Object
        })
        .then(result => {
           console.log(data);
           setData(oldState => ({ ...oldState, data: result})); // <<- Merge previous state with new data
        })
        .catch(error => { // Use .catch() to catch exceptions. Either in the request or any of your .then() blocks
            console.error(error); // Log the error object in the console.
            const errorMessage = 'Something went wrong';
            setData(oldState=> ({ ...oldState, placeholder: errorMessage }));
        });

    },[]);

    return (
      <h1>{console.log(data)}</h1>
    );
}

Ohne Staatsobjekt

export default function App() {
    const [data, setData] = useState([]);
    const [loaded, setLoaded] = useState(false);
    const [placeholder, setPlaceholder] = useState('Loading');

    // Fetch and update date
    useEffect(() => {
        fetch('http://localhost:8000/api/lead/')
        .then(response => {
            if (response.status !== 200) {
                throw new Error(response.statusText); // Goto catch block
            }
            return response.json(); // <<- Return the JSON Object
        })
        .then(result => {
           console.log(data);
           setData(data);
        })
        .catch(error => { // Use .catch() to catch exceptions. Either in the request or any of your .then() blocks
            console.error(error); // Log the error object in the console.
            const errorMessage = 'Something went wrong';
            setPlaceholder(errorMessage);
        });

    },[]);

    return (
      <h1>{console.log(data)}</h1>
    );
}
1
Linschlager 21 Feb. 2020 im 10:30

Ihr Code enthält 3 Fehler

.then(response => {
            if (response.status !== 200) {
                setData({...data, placeholder: 'Something went wrong'});
            }
            return response.json() // <====== HERE: you need to return the response.json()
        })
.then(result => {
           console.log(data);
           setData({...data, data: result}); // <==== HERE, you need to spread data first
        });
2
menett_a 19 Feb. 2020 im 17:16

Der richtige Weg, ein Objekt mit Hooks zu aktualisieren, um die Funktionssyntax für den setState-Rückruf zu verwenden:

setData(prevState => {...prevState, placeholder: 'Something went wrong'})

Die folgende Methode überschreibt Ihren vorherigen Objektstatus:

setData({placeholder: 'Something went wrong'}); // <== incorrect

Ihr endgültiger Code sollte folgendermaßen aussehen:

.then(response => {
    if (response.status !== 200) {
        setData(prevObj => {...prevObj, placeholder: 'Something went wrong'});
    }
    return response.json()
 })
.then(result => {
    setData(prevObj => {...prevObj, data: result});
 });
0
Sushmit Sagar 19 Feb. 2020 im 17:35