简体   繁体   中英

useState referring to stale value

I have a keeper app where I am adding notes and storing them in database. When I make a post request to the server, I am trying to fetch the _id from database, which will eventually help me to later delete the note ( if needed). Here is my jsx file

function CreateMessage(props) {   

    const [currentGuest, setCurrentGuest] = useState({
        guestName: '',
        guestMessage: '',
        id:''
    });

    function handleMessages(event) {
        const {name, value} = event.target;
        setCurrentGuest(prevGuest => {
            return {
                ...prevGuest,
                [name] : value
            };
        });
    }


    function submitMessage(event) {
    //props.onAdd(currentGuest);
    const params = {
      guestName: currentGuest.guestName,
      guestMessage: currentGuest.guestMessage,
    }
    axios
    .post("http://localhost:8000/notes", params)
    .then(res => {
      console.log("The response is"+res.data._id);
      console.log(res.status);
      setCurrentGuest(prevGuest => {
        console.log(res.data._id)
            return {
                ...prevGuest,
                id: res.data._id
            };
        });
        console.log(currentGuest);
    })

    event.preventDefault();
    }

    return (
    <div>
      <form>
        <input
          name="guestName"
          placeholder="Guest Name"
          value={currentGuest.guestName}
          onChange={handleMessages}
        />
        <textarea
          name="guestMessage"
          placeholder="Write a Message"
          rows="3"
          value={currentGuest.guestMessage}
          onChange={handleMessages}
        />
        <button onClick={submitMessage}>Add</button>
      </form>
    </div>
  );

}

The id is properly being fetched and displayed in ```console.log("The response is"+res.data._id"). But on first submit, the is always empty and stale id gets attached to the currentGuest object on next submit

function submitMessage(event) {
//props.onAdd(currentGuest);
const params = {
  guestName: currentGuest.guestName,
  guestMessage: currentGuest.guestMessage,
}
axios
.post("http://localhost:8000/notes", params)
.then(res => {
  console.log("The response is"+res.data._id);
  console.log(res.status);
  setCurrentGuest(prevGuest => {
    console.log(res.data._id)
        return {
            ...prevGuest,
            id: res.data._id
        };
    });
    console.log(currentGuest);
})

event.preventDefault();
}

In the above snippet, after getting the response you're correctly changing the state but the problem is with where you're checking the changed state( console.log(currentGuest) ). You're basically logging before the state is changed.

You can use useEffect hook and log the state inside it. This runs every time the currentGuest Changes.

useEffect(() => {
 console.log(currentGuest)
}, [currentGuest])

Update

You can use the modified currentGuest inside the useEffect hook:

useEffect(() => {
  console.log(currentGuest)
  if(currentGuest.id) {
   props.onAdd(currentGuest);
   // You can also reset the state here as follows
   setCurrentGuest({
    guestName: '',
    guestMessage: '',
    id:''
   });
  }
}, [currentGuest]) // You might need to add the necessary dependencies to this array.

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