0

I'm working an a react app with a few forms and I am trying to implement an edit form for input items. The function first opens the list item in a pre-populated form. The editItem function currently looks like this:

editItem(event) {
    event.preventDefault();
    const target = event.target.parentNode.parentNode;
    const { key } = target.dataset;
    const { className } = target;
    const currState = { ...this.state[className] };
    const currItem = currState.list[key];
    for (let i in currItem) {
      if (i !== "list" && i !== "hidden") {
        currState[i] = currItem[i]
      }
    }
    this.setState({ [className]: currState });
    this.hideUnhide({target: {name: className}});
 

     }

I have confirmed with console logs that currState is correctly set with the values that I am looking for, and that I am not having an async issue. I am using this same format to set state in other functions in my app and all of the others are working properly. If I directly mutate state in the same place, I get the behavior I'm looking for (form fields populate), but nothing happens when I use setState.

Link to my github repo: here. The function in question is in App.js.

3
  • 1
    I took a quick look at your repo and it looks like you're also updating the same state key in the hideUnhide function? If I'm understanding that correctly, that will be your problem. State updates are batched if called in the same render, and the most recent will overwrite the previous. Commented May 28, 2021 at 13:17
  • 1
    Aha! putting the hideUnhide call into a callback for the setState fixes the issue! Thank you very much! Commented May 28, 2021 at 13:20
  • Duplicate of What happens when using this.setState multiple times in React component? Commented May 28, 2021 at 13:27

1 Answer 1

1

As Brian Thompson points out in his comment, it turns out that the hideUnhide function call directly after my setState uses setState as well and writes over the first setState call with the previous state:

  hideUnhide(event) {
    const { name } = event.target;
    const currState = { ...this.state[name] };
    if (currState.hidden === true) {
      currState.hidden = false;
    }
    this.setState({ [name]: currState });
  }

The way to prevent that was to use hideUnhide as a callback to the setState in editItem:

this.setState({ [className]: currState }, () =>
  this.hideUnhide({ target: { name: className } })
);

and now everything functions as intended.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.