動機
以前から React を自作しよう を見かけてやりたいと思っていたが GW でやっとまとまった時間が取れたのでじっくり取り込んだ。
React をよく個人的に使うので、その設計と実装を経験したほうが React への理解が深まるのでは?と思った。
TL;DR
作業結果は下記のリポジトリにアップした。
https://github.com/ryokryok/practice-diy-react
感想
記事の中で実装したのは下記の React の関数を簡素化したものだった。
React.createElement
React.useState
ReactDOM.render
実際手を動かした見た所感は下記。
- 本当に 1 からの実装して数百行のコードで React の関数を置き換えるので面白かった
/** @jsx Didact.createElement *
とコメントを書くだけで JSX の変換関数が置き換わるのを知ったFiber
という作業単位によって効率よくレンダリングするというのが理解できた- JSX が取りうる構造を想定しながらそれを実装に落とし込む方法が理解できた
- HTML の要素が親子関係、または兄弟関係を想定するなど
- どのように差分検出するのか、というのを理解できた
- 更新か、追加か、削除かなどを判定するためにどのような実装
- 型がない JavaScript での実装なので、作業中にどのような Object の実装を目指しているのかちょっとわかりにくかった
環境構築
翻訳版にも元記事にも環境構築はなく、悩んだが Babel で JSX を JS に変換したときの挙動を確認する手順があったため、開発用にBabel + Webpack でセットアップして、変換確認用に script を設定した。
Babel のプラグインに関してはただ単純に変換した結果を見たいため、@babel/preset-react
だけ入れた。
通常なら "@babel/preset-env"
も入れるが今回はパス。
{ "presets": ["@babel/preset-react"] }
package.json
にて scripts を追加して yarn transform
すればJSX を JS の関数に変換した結果が temp
ディレクトリーに展開される。
"scripts": { "transform": "babel src -d temp", "dev": "webpack serve", "build:dev": "webpack --mode=development", "build": "webpack --mode=production" },
記事中にもあったがコメントで @jsx Didact.createElement
と書くと JSX の変換用関数を別のものに指定できる。
(標準では React.createElement
が指定される)
公式では下記に記載がある。例として Preact の変換用関数の記載がある。
@babel/plugin-transform-react-jsx
後は Webpack を入れて、 babel-loader で変換するようにするだけ。Webpack の設定は素朴なので詳細はリポジトリを見てください。
自分以外にやってみた人の記事を見ると create-react-app
したのを eject していた。
https://blog.shibayu36.org/entry/2021/04/15/173000