Home > database >  setState not updating an object straight away
setState not updating an object straight away

Time:01-27

I have a form and when the submit button is clicked I am trying to store the values from each field into an object so I can send the object in a POST request. The first time I click submit, I get the default state of the object with empty properties and then when I click it again, the object properties update. This keeps happening as I change the values in the input fields, it is always one step behind.

Here is the default state and the function that is replacing the object. This gets called in the button onClick.

const [formResponse, setFormResponse] = useState({
    name: "",
    projectTitle: "",
    projectDescription: "",
    projectGoal: "",
    projectOutcome: ""
  });

  function submitFormResponse(e) {
    e.preventDefault();
    setFormResponse((formResponse) => ({
      ...formResponse,
      name: name,
      projectTitle: title,
      projectDescription: description,
      projectGoal: goal,
      projectOutcome: outcome
    }));

    console.log(formResponse);
  }

Here is a codesandbox version of what's happening.

I can't figure out why this might be happening. Any help is greatly appreciated!

CodePudding user response:

You cannot update the state immediately, From the docs

State Updates May Be Asynchronous
React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

Check this

//Here is your code modification
import React, { useState } from "react";

export default function Form() {
  const [name, setName] = useState("");
  const [title, setTitle] = useState("");
  const [description, setDescription] = useState("");
  const [goal, setGoal] = useState("");
  const [outcome, setOutcome] = useState("");
  const [formResponse, setFormResponse] = useState({
    name: "",
    projectTitle: "",
    projectDescription: "",
    projectGoal: "",
    projectOutcome: ""
  });

  function submitFormResponse(e) {
    e.preventDefault();
    // Create a object to hold values
    const formResult = {
      name: name,
      projectTitle: title,
      projectDescription: description,
      projectGoal: goal,
      projectOutcome: outcome
    }
    //Write post request logic and send `formResult`

    // setFormResponse((formResponse) => ({
    //   ...formResponse,
    //   name: name,
    //   projectTitle: title,
    //   projectDescription: description,
    //   projectGoal: goal,
    //   projectOutcome: outcome
    // }));

    console.log(formResult);
  }

  return (
    <form>
      <input
        name="name"
        type="text"
        placeholder="Name"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <input
        name="projectTitle"
        type="text"
        placeholder="Project title"
        value={title}
        onChange={(e) => setTitle(e.target.value)}
      />
      <textarea
        name="projectDescription"
        placeholder="Project description"
        value={description}
        onChange={(e) => setDescription(e.target.value)}
      ></textarea>
      <input
        name="goal"
        type="text"
        placeholder="Project goal"
        value={goal}
        onChange={(e) => setGoal(e.target.value)}
      />
      <textarea
        name="outcome"
        placeholder="Project outcome"
        value={outcome}
        onChange={(e) => setOutcome(e.target.value)}
      ></textarea>
      <button type="submit" onClick={submitFormResponse}>
        Submit
      </button>
    </form>
  );
}


CodePudding user response:

This is normal React behavior, state value changes happen asynchronously, to change synchronously you can use useRef hook, or you can use useEffect hook to listen for state changes and always get the latest value updated.

  • Related