Reputation: 105
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
Reputation: 8011
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
Reputation: 5766
Setting the state is an asynchronous operation, so it's expected that both of your console.log
s 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