Reactのコンポーネントの描画(render、表示)はReactライブラリーが制御していて、Reactに不慣れなプログラマーには思わぬタイミングで描画される事があります。
しかしReactで描画が行われるのは以下の場合です
- React(JavaScript)のコードがブラウザーに読み込まれた直後
- コンポーネントの引数(props)が変わったとき
- コンポーネントの管理する状態(ステータス、state)が変わったとき
- Contextを参照しているコンポーネントで、Contextの値が変わったとき
React教育を行っているとReactに不慣れな受講者は、ときどき不思議なコードを書いてくれます。
以下のコードを実行すると、描画が起きるのは1.のみで、ブラウザーの画面にはcount = 1と表示されるように思えます。
(このコードはReactの設計思想からすると望ましくないコードですが、初心者は書いてしまいがちなコードです)
import React from 'react'
let count = 0
export const App: React.FC = () => {
count++
console.log(`count: ${count}`)
return (<div>count = {count}</div>)
}
しかし、なぜか以下のようにcount = 2と表示されます!
環境は最新のcreate-react-app(react: 17.0.1, react-scripts: 4.0.1, typescript: 4.0.5, node.js: 14.15.0)で作った環境です。
プロダクション用コードで試す
npm run build
で、プロダクション(本番)用コードを生成し、それをnginxで動かすと下の画像のようにcount = 1と表示されます。論理的にあっています 😀
開発環境ではコンポーネントが2回描画されている
下のようにconsole.log()の後ろにalert()を追加して実行してみました。
import React from 'react'
let count = 0
export const App: React.FC = () => {
count++
console.log(`count: ${count}`)
alert(`count: ${count}`)
return (<div>count = {count}</div>)
}
alertは2回表示されます、しかもalertに表示されるcountの値も思った通りの値です。しかし、console.logには1しか表示されていません。
今日の結論
ここまでの結論は、
- create-react-appで作った開発環境では、コンポーネントが2回描画(実行)される場合がある
- これはコードの変更が直ぐに画面に反映される、ホットリロードに関係するのでしょうか?
- しかし、console.logは1回しか表示されない
- この現象はプロダクション環境では起きない
- Reactの設計思想にそったコードなら、2回描画されても問題は起きない
原因は開発環境で使われているコードを読んでみないと判らないと思います、
初心者は思わぬコードを書きます😀 そこからシステムの深淵が顔を覗かせたようですね。