skip to Main Content

why is the state only updated in the last if en else statement.
only the age in setFilledIn is set to true and false

Can someone help me to understand state in React?
because I don’t know what I am doing wrong.

btw if I comment out the last if statement then the if statement for lastName works.

const [filledIn, setFilledIn] = useState({
firstName: true,
lastName: true,
age: true,
});

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (firstNameRef.current == null || firstNameRef.current.value === "") {
  setFilledIn({ ...filledIn, firstName: false });
} else {
  setFilledIn({ ...filledIn, firstName: true });
  person2.firstName = firstNameRef.current.value;
}
if (lastNameRef.current == null || lastNameRef.current.value == "") {
  setFilledIn({ ...filledIn, lastName: false });
} else {
  setFilledIn({ ...filledIn, lastName: true });
  person2.lastName = lastNameRef.current.value;
}

 if (ageRef.current == null || ageRef.current.value == "") {
   setFilledIn({ ...filledIn, age: false });
 } else {
   setFilledIn({ ...filledIn, age: true });
   person2.age = parseInt(ageRef.current.value);
 }

};

2

Answers


  1. This post is hidden. You deleted this post 2 mins ago.
    The issue is that you’re updating the state separately for each field, so only the last field’s update will be reflected in the final state. This is because the setFilledIn function calls are asynchronous, and each call overwrites the previous update.

    To fix this, you can update the state once at the end of the function, after checking all the fields.

    const [filledIn, setFilledIn] = useState({
      firstName: true,
      lastName: true,
      age: true,
    });
    
    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      let updatedFilledIn = { ...filledIn };
    
      if (firstNameRef.current == null || firstNameRef.current.value === "") {
        updatedFilledIn.firstName = false;
      } else {
        updatedFilledIn.firstName = true;
      }
    
      if (lastNameRef.current == null || lastNameRef.current.value === "") {
        updatedFilledIn.lastName = false;
      } else {
        updatedFilledIn.lastName = true;
      }
    
      if (ageRef.current == null || ageRef.current.value === "") {
        updatedFilledIn.age = false;
      } else {
        updatedFilledIn.age = true;
      }
    
      setFilledIn(updatedFilledIn);
    };
    

    or you can simplify it to

    const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      let updatedFilledIn = { ...filledIn };
    
      const fields = {
        firstName: firstNameRef,
        lastName: lastNameRef,
        age: ageRef,
      };
    
      Object.entries(fields).forEach(([fieldName, fieldRef]) => {
        if (fieldRef.current == null || fieldRef.current.value === "") {
          updatedFilledIn[fieldName] = false;
        } else {
          updatedFilledIn[fieldName] = true;
        }
      });
    
      setFilledIn(updatedFilledIn);
    };
    
    
    Login or Signup to reply.
  2. I haven’t tested this, so it only qualifies as an educated guess. But I’m going to assume it has something to do with your user of the spread utility (the …) each time you call setState. Technically you shouldn’t need these since you’ve already initialized the state with useState. But if you want to use them instead of initializing the state then you’ll have to put [] around your namespace in the keypair. For example:

    setFilledIn({ ...filledIn, [lastName]: false });
    

    or

    setFilledIn({ lastName: false });
    

    Hope this helps! Here is a good explanation of setState and useState hooks.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search