Mindaugas Nakrošis
Mindaugas Nakrošis

Reputation: 105

Changing state value in async event function

I have a React component:

const Calendar = ({ onEventDrag }) => {
  const [editable, setEditable] = useState(true);

  const eventChange = async event => {
    setEditable(false);
    console.log('before await');
    console.log(editable);
    await onEventDrag(event);
    console.log('after await');
    setEditable(true);
    console.log(editable);
  };

  return (
        <FullCalendar
          editable={editable}
          eventChange={eventChange}
        />
  );
};

onEventDrag is an async API call function passed through props to this component.

I want to set editable state value to false when eventChange function is called and only set it to true when onEventDrag async function returns something.

What console logs with this code currently:

before await
true
after await
true

Upvotes: 1

Views: 73

Answers (2)

Firstly, your code works fine but the console logs the old value.

To understand this behavior you have to understand how closures work in javascript. When you define a function, any surrounding variables are made part of the function "scope". When you call setEditable(), react calls Calendar() again with a new state.

However, the eventChange function is still running! This is not a problem, since setEditable stays the same. However, the local variable editable will become outdated and no longer represent the actual state of the component.

Upvotes: 1

larz
larz

Reputation: 5766

Setting the state is an asynchronous operation, so it's expected that both of your console.logs will output true. However, if you put console.log(editable) outside of eventChange, you should see it update appropriately on the next render.

Upvotes: 2

Related Questions