最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I update an object state in react via hooks - Stack Overflow

programmeradmin0浏览0评论

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 ponents 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 ponent, Its a single ponent 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'));

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 ponents 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 ponent, Its a single ponent 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'));
Share Improve this question edited Feb 19, 2020 at 17:23 Romeo asked Feb 19, 2020 at 17:09 RomeoRomeo 7881 gold badge6 silver badges25 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 5

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

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});
 });
发布评论

评论列表(0)

  1. 暂无评论