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 先のコードの副作用が実行されます。
parent
は childB
そして 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
そしてついに上記モジュールから parent
の execParent()
が実行されます。
その中で 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