React自作

少し前に話題になっていたReact自体の自作をやってみた。 一日かからないくらいの時間で、実装できるし、Reactの動作をかなりこまかく理解できるようになったので、React書く人にはお勧めしたい。

zenn.dev

自分が書いたのは以下。ほぼ写経。 github.com

気づき

やってみての気づきはいくつかある。

まず、DOMに対応するFiberというデータ単位で、仮想的なDOMツリーを構築し、更新を管理していることを理解できた。 Fiberが具体的にどんなデータを持っていて、何を管理しているのかがある程度わかった。

次に、DOMツリー構築の順序というかアルゴリズムも理解できた。 Render PharseとCommit Pharseの2Pharseそれぞれの具体的な役割がわかった。 (例えば、DOMの作成は、Render Pharseで、親のDOMへのappendChildはCommit Pharseでやっているというような。)

さらに、Hooksがどう動くかも理解できた。具体的には、setStateを呼ぶと処理自体はfiber内のqueueに積まれて、Render Pharseでのfiber自体の差分更新処理時に反映される、といった細かい振る舞いの理解ができた。

あとはrequestIdleCallbackというJavascriptの関数を知った。これ裏で重い処理したい場合はとても重宝する。

そんなところ。

tsx/jsxの変換

ちょっとしたメモの共有。

Reactの前にjsx/tsxをjsに変換できるように解釈が必要だが、そのあたりのやり方がわからず、自分はちょっと詰まった。

viteでやったので、tsconfigをちょっと編集して対応した。(MyReactという名前にした。)

{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "MyReact.createElement",
    "allowJs": true,
    ....
  },
  ...
}

そうではなくて単純に、以下のbabel用のアノテーションをつけるだけでもよかったかも。

/** @jsx MyReact.createElement */
const element = <div>Hello</div>;

vite使わずに、素のtypescriptだけでも、jsxをjsに簡単に変換できる。

tsc --jsx react --allowJs hello.jsx

ちなみに、自作するReact自体はTypescriptで書いたが、ただし、自作したReactを使って動くコードをtsxやtsで加工とすると、TSXの型定義で苦労しそうだったので、そこはjsxで書いた。