Skip to content

Import module in React several times. Is the code executed once vs executed multiple times

Everything started from the need to do a configuration in a function call and figure out what happened if imported in more than one file.

I have this function

function.js
export function myFunction() {
  let b = Math.random();
  return b;
}

Two cases. Import the function directly and display it in several places. Different values are displayed. First case

App.js
import myFunction from "./myFunction";
export default class App extends Component {
  render() {
    return (
      <div className="App">
        <h3>{myFunction()}</h3>
        <h3>{myFunction()}</h3>
      </div>
    );
  }
}

Second case.

counter.js
import myFunction from "./myFunction";
export default myFunction(7)

App.js
import counter1 from "./counter";
import counter2 from "./counter";

export default class App extends Component {
  render() {
    return (
      <div className="App">
        <h3>counter1</h3>
        <h3>counter2</h3>
      </div>
    );
  }
}

In this second case, the same value is displayed.

There is an article here :https://dmitripavlutin.com/javascript-module-import-twice/ Still could not completely explain what happens though

Answer

In the first scenario, there are two separate calls to myFunction,
that is to say two separate calls to Math.random() (considering its implementation).

In the second scenario, counter1 and counter2 refer to the same './counter' module instance.
This instance exposes a constant (i.e.: myFunction(7)) which has been initialized at module instantiation:

  • When the import counter1 from './counter'; statement is read:
    • It looks if the './counter' module has already been evaluated
    • As it is not the case, it evaluates the './counter' module
    • At this moment, the constant myFunction(7) is created (let’s assume it equals 0.12345)
      and exposed as the default export of the './counter' module instance
    • Then, in App.js, the counter1 variable takes the value 0.12345
  • When the import counter2 from './counter'; statement is read:
    • It looks if the './counter' module has already been evaluated
    • As it has already been imported/evaluated with the same path,
      it returns the same & existing './counter' module instance
    • It looks at its default export, which is 0.12345
    • Thus, in App.js, the counter2 variable also takes the value 0.12345

That is why the same value is displayed.