简体   繁体   中英

How do I update an object state in react via hooks

This is a simple question. How do I successfully update state object via react hooks?

I just started using hooks, and I like how it allows to use the simple and pure JavaScript function to create and manage state with the useState() function, and also, make changes that affect components using the useEffect() function, but I can't seem to make update to the state work!

After making a request to an API, it return the data needed, but when I try to update the state for an error in request and for a successful request, it does not update the state. I logged it to the browser console, but no change was made to the state, it returns undefined.

在此处输入图片说明

I know that I'm not doing something right in the code. Here is my App component, Its a single component for fetching and updating:

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'));

There are a few things you can improve:

  • the react-hook useState does not behave like the class counterpart. It does not automatically merge the provided object with the state, you have to do that yourself.
  • I would recommend if you can work without an object as your state to do so as this can reduce the amount of re-renders by a significant amount and makes it easier to change the shape of the state afterwards as you can just add or remove variables and see all the usages immediately.

With a state object

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>
    );
}

Without a state object

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>
    );
}

This is a simple question. How do I successfully update state object via react hooks?

I just started using hooks, and I like how it allows to use the simple and pure JavaScript function to create and manage state with the useState() function, and also, make changes that affect components using the useEffect() function, but I can't seem to make update to the state work!

After making a request to an API, it return the data needed, but when I try to update the state for an error in request and for a successful request, it does not update the state. I logged it to the browser console, but no change was made to the state, it returns undefined.

在此处输入图片说明

I know that I'm not doing something right in the code. Here is my App component, Its a single component for fetching and updating:

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'));

The correct way to update an Object with hooks it to use function syntax for setState callback:

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

Following method will override your previous object state:

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

Your final code should look like this:

.then(response => {
    if (response.status !== 200) {
        setData(prevObj => {...prevObj, placeholder: 'Something went wrong'});
    }
    return response.json()
 })
.then(result => {
    setData(prevObj => {...prevObj, data: result});
 });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM