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.

Jonathan Potter
  • 147
  • 1
  • 10
  • 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. – Brian Thompson May 28 '21 at 13:17
  • 1
    Aha! putting the hideUnhide call into a callback for the setState fixes the issue! Thank you very much! – Jonathan Potter May 28 '21 at 13:20
  • Duplicate of [What happens when using this.setState multiple times in React component?](https://stackoverflow.com/questions/33613728/what-happens-when-using-this-setstate-multiple-times-in-react-component) – Brian Thompson May 28 '21 at 13:27

1 Answers1

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.

Jonathan Potter
  • 147
  • 1
  • 10