Reactのコンポーネントの外側の処理の実行タイミング

Reactのコンポーネントの外側の処理の実行タイミング

February 17, 2022

Parent コンポーネントが ChildA および ChildB をインポートとしているとして、それぞれのコンポーネントで以下のように console.log() しているとどの順番に出力されるのか。

Parent.jsx

import { ChildB } from './ChildB';
import { ChildA } from './ChildA';

console.log('Parent | Outer Top');

export function Parent() {
  console.log('Parent | Inner');
  return (
    <>
      <ChildA />
      <ChildB />
    </>
  );
}

console.log('Parent | Outer Bottom');

ChildA.jsx

console.log('Child A | Outer Top');

export function ChildA() {
  console.log('Child A | Inner');
  return <></>;
}

console.log('Child A | Outer Bottom');

ChildB.jsx

console.log('Child B | Outer Top');

export function ChildB() {
  console.log('Child B | Inner');
  return <></>;
}

console.log('Child B | Outer Bottom');

結果 #

Child B | Outer Top
Child B | Outer Bottom
Child A | Outer Top
Child A | Outer Bottom
Parent | Outer Top
Parent | Outer Bottom
Parent | Inner
Child A | Inner
Child B | Inner

説明 #

よく考えてみると上記結果になるのは当然のことで、React だからとつい特別に考えてしまいがちですが、通常の JavaScript に還元して考えると、以下のコードを実行しているのと同じことです。

parent.js

import { childB } from './childB';
import { childA } from './childA';

console.log('Parent | Outer Top');

export function execParent() {
  console.log('Parent | Inner');
  execChildA();
  execChildB();
}

console.log('Parent | Outer Bottom');

childA.js

console.log('Child A | Outer Top');

export function execChildA() {
  console.log('Child A | Inner');
}

console.log('Child A | Outer Bottom');

childB.js

console.log('Child B | Outer Top');

export function execChildB() {
  console.log('Child B | Inner');
}

console.log('Child B | Outer Bottom');

import したとき、まずは import 先のコードの副作用が実行されます。

parentchildB そして childA の順番で import しているため、先に childB の副作用が実行されます。

Child B | Outer Top
Child B | Outer Bottom

次に childA の副作用が動きます。

Child B | Outer Top
Child B | Outer Bottom
Child A | Outer Top
Child A | Outer Bottom

また parent も別の上位モジュールから import されている存在です。そのため次に parent の副作用が動きます。

Child B | Outer Top
Child B | Outer Bottom
Child A | Outer Top
Child A | Outer Bottom
Parent | Outer Top
Parent | Outer Bottom

そしてついに上記モジュールから parentexecParent() が実行されます。

その中で execChildA() そして execChildB() の順番で実行されていますので、最終的な出力は以下となります。

Child B | Outer Top
Child B | Outer Bottom
Child A | Outer Top
Child A | Outer Bottom
Parent | Outer Top
Parent | Outer Bottom
Parent | Inner
Child A | Inner
Child B | Inner