少し前に話題になっていたReact自体の自作をやってみた。 一日かからないくらいの時間で、実装できるし、Reactの動作をかなりこまかく理解できるようになったので、React書く人にはお勧めしたい。
自分が書いたのは以下。ほぼ写経。 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で書いた。