Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code in async function executed twice when called from React

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.

like image 225
Erik Hermansen Avatar asked Sep 17 '25 02:09

Erik Hermansen


1 Answers

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.

like image 99
Erik Hermansen Avatar answered Sep 19 '25 18:09

Erik Hermansen