Here is my minimal code to show the issue:
async function doSomeThings(caller) {
console.log('Step 1 for ' + caller);
await 1;
console.log('Step 2 for ' + caller);
}
function TestAsyncComponent() {
doSomeThings('React component');
return null;
}
doSomeThings('module');
export default TestAsyncComponent;
The TestAsyncComponent
is simply rendered inside of a page. The code that does that is essentially just the boilerplate generated by create-react-app. But if you want to see it, I'll drag it in.
When TestAsyncComponent
is imported and then rendered, console output shows the following:
Step 1 for module
Step 2 for module
Step 1 for React component
Step 2 for React component
Step 2 for React component
There is something about calling the async function from the React function during rendering that causes a portion of the code inside the async function to execute twice. That's totally unexpected to me.
Note - the async function isn't called twice. If that were the case, then "Step 1 for React component" would be output twice. Execution occurs twice for the code after the "await 1" statement within the async function.
How do I prevent this called-twice-from-React behavior? Also, I'm very interested in the explanation of why the code after "await 1" is called twice.
The OP's original premise that the async function isn't called twice is incorrect. Console logging was suppressed for one output of the console.log('Step 1 for ' + caller)
line. But setting a breakpoint in the debugger proved execution came to this line twice instead of once.
The problem can be fixed with useEffect()
like so:
function TestAsyncComponent() {
useEffect(() => {
doSomeThings('React component');
return null;
}, []);
}
This works because the call to doSomeThings()
will only be called once.
Self-answering to just have an answer on record for the question. Thanks to those who helped above in comments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With