0

I just found this function in code and not sure if it can actually work, because it tries to update two state variables sequentially

changeIsOpen and changeInputValue are state setters, it looks wrong for me

  const toggleOpen = (
    event: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ): void => {
    event.preventDefault()
    const newOpenState: boolean = !isOpen
    changeIsOpen(newOpenState)

    const curItem: SelectSuggestV2Item | undefined = items.find(
      (item: SelectSuggestV2Item) => item.id === selectedId
    )

    // If closed and a search was in progress, restore the last selected value
    if (!newOpenState && curItem != null && curItem.label !== inputValue) {
      changeInputValue(curItem.label)
    }
  }
jeff
  • 1,169
  • 1
  • 19
  • 44
  • 2
    Yes this works fine. Since different states are set, both will be applied. Since set setting of state is async. – Domino987 Aug 28 '19 at 15:22
  • Seems good to me, have you tried the code to see if its working or not? – Rikin Aug 28 '19 at 15:25
  • You're right; the state setters are asynchronous, so setting `newOpenState` and then checking it soon after could be a race condition. Here's a solution: https://stackoverflow.com/a/53914175/2112512 – Jake Worth Aug 28 '19 at 15:25
  • Possible duplicate of [Executing async code on update of state with react-hooks](https://stackoverflow.com/questions/53898810/executing-async-code-on-update-of-state-with-react-hooks) – Andrew Aug 28 '19 at 16:45

1 Answers1

0

Since the snippet is not reading the isOpen state value after changing it, but instead is relying on its local newOpenState value, it should be working as intended.

If you have more complex code where you are reading / writing to / from multiple state values, you might want to consider using the React.useReducer hook instead.

Also multiple set calls in the same tick, should be properly batched by React and wont cause multiple rerenders.

Nappy
  • 3,016
  • 27
  • 39