めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

バックエンドエンジニアのための「React の仕組み」の理解方法

何の話かと言うと

普段、UI に関わらないバックエンドのコンポーネントを作っているエンジニアがフロントエンドのコーディングを理解しようとすると、色々と異次元な世界で混乱する(というか何をやっているのかをすぐに忘れる)ので、バックエンドエンジニアにわかりやすい形で React の仕組み(メンタルモデル)をまとめてみました*1

  • ブラウザの画面に描画される個々の要素を「コンポーネント」と呼ぶ。
  • 自分で定義したコンポーネントを HTML タグを使って表示することができる。
  • コンポーネントは関数として定義する。この関数は、HTML タグで指定された時の属性値を受け取って、コンポーネントを実際に描画する HTML の塊(React 要素)を返す。(つまり、コンポーネントを指定した HTML タグが、コンポーネントからの返り値の React 要素で置換される。)
  • Javascript の関数はクロージャーなので、内部状態を持つことができる。つまり、*2個々のコンポーネントは内部状態を持つことができる。特にReact では、関数 useState()、useRef() を利用して、呼び出しごとに初期化されない状態変数を用意する。
  • useState() で用意される状態変数(state オブジェクト)に保持した値を変更すると、自動的にコンポーネントの再描画が行われる。一方、useRef() で用意される状態変数(ref オブジェクト)の変更はコンポーネントの再描画を引き起こさない。
  • コンポーネントを定義した関数内でイベントハンドラーを登録しておき、イベント発生時に関数内で定義したハンドラー関数を実行することができる。
  • useEffect() 関数を利用すると、参照渡しで受け取っておいた外部のオブジェクトが変更された事をイベントとして受け取ることもできる。

というわけで、複数のコンポーネントを画面上に表示しておき、あとは、非同期なイベントの連鎖でコンポーネントの内部状態が変化していって、state オブジェクトが変化したタイミングで該当コンポーネントの再描画が発生して画面が変化する、というのが本質的な仕組みになります。

コンポーネントの親子関係

コンポーネント A が返す React 要素の中に、他のコンポーネント B を含む場合、コンポーネント A は「親コンポーネント」、コンポーネント B は「子コンポーネント」になります。この際、親子間でのデータの受け渡しや関数の実行に React 特有の方法が必要となります*3

  • 親から子にデータを受け渡す:子コンポーネントを指定したタグの属性値が、子コンポーネントを定義する関数の引数として受け渡される。(連想配列 props でまとめて受け取る。)
  • 子から親にデータを受け渡す:親コンポーネントの状態変数(ref オブジェクト)を props として子コンポーネントに受け渡しておき、子コンポーネントから更新する。もしくは、親コンポーネントの状態変数(state オブジェクト)を更新する関数を props として子コンポーネントに受け渡しておき、子コンポーネントから実行する。
  • 親が子の関数を実行する:親コンポーネントの状態変数を props として子コンポーネントに受け渡しておき、子コンポーネント側では、useEffect() を用いて、その値の変化をトリガーとして関数を実行するように仕込んでおく。あとは、親コンポーネントで状態変数を書き換えると、子コンポーネントの関数が実行される。
  • 子が親の関数を実行する:親コンポーネントの関数を props として子コンポーネントに受け渡しておき、子コンポーネントから実行する。

追記

こちらの連載記事も参考にしてください。

enakai00.hatenablog.com

*1:「僕は言いたいことを理解できるけど、Reactやってない人にはサッパリなんじゃないかなと思う。つまり「ReactエンジニアのためのReactの仕組み」になってるんだけど、それに気づけるかはセンスとしか言いようがない」というコメントをいただきました。「お前はセンスが無い」と指摘されているようで心が折れかけましたが、すくなくとも、Reactエンジニアには理解できる(つまり、概ね間違っていない)内容になっているものと前向きに捉えることにしました。

*2:「"Javascript の関数はクロージャーなので、内部状態を持つことができる。つまり、個々のコンポーネントは内部状態を持つことができる。" しれっと言っているが Hooks の状態はクロージャーに保持されるわけではない」とのコメントをいただきました。

*3:「いや親子間のデータ明け渡しはもっと色々あるだろ言うべきことが」とのコメントをいただきました。