Edited at

Reactのrendererを見よう見まねで作ってみる


事の発端



ほう😮



自己紹介

今は主にフロントをやっていて、React,React-Native,Vueとかを普段は触っています。



つくったもの


react-voice

🔈React for Voice User Interface apps

https://github.com/hand-dot/react-voice



どういうもの?

react-voiceのrendererを書いて、node上で動くVoice User InterfaceのためのReactをかけるようにしました。



デモ



ここまでのあゆみ


  1. [昨日の夕方] ツイート見る

  2. [昨日の夜] 開発



    • ink のコードを読む

    • 上を参考にレンダラーとコンポーネントを実装

    • PCが突然しゃべりはじめる



  3. [今] 俺がしゃべっている



inkって?


ink

🌈 React for interactive command-line apps

ターミナル用のReactのレンダラーで、facebookのjestにも使われているらしい

コードも小さいので参考になりました。



コードベース

|--src

| |--components
| | |--Speak.jsx ←喋るコンポーネント
| | |--AsyncSpeak.jsx ←次の処理を待って喋るコンポーネント
| |--index.js ←今はサンプルコード
| |--render.js ←レンダーの関数
| |--speak.js ←喋る関数



コードベース

|--src

| |--components
| | |--Speak.jsx ←喋るコンポーネント
| | |--AsyncSpeak.jsx ←次の処理を待って喋るコンポーネント
| |--index.js ←今はサンプルコード
| |--render.js ←レンダーの関数 🔴
| |--speak.js ←喋る関数



レンダーの関数を見せてもらおうか😏

どれどれー?


render.js

import ReactReconciler from "react-reconciler";

const reconciler = ReactReconciler({
now: Date.now,
getRootHostContext: () => null,
prepareForCommit: () => null,
resetAfterCommit: () => null,
getChildHostContext: () => null,
shouldSetTextContent: () => null,
createInstance: () => null,
createTextInstance: () => null,
appendInitialChild: () => null,
finalizeInitialChildren: () => null
});

const render = node => {
reconciler.updateContainer(node, reconciler.createContainer());
};

export default render;




nullみが強い🤪



ところでこいつだれ?


render.js

import ReactReconciler from "react-reconciler"; // ←だれ?🙄

const reconciler = ReactReconciler({
now: Date.now,
getRootHostContext: () => null,
prepareForCommit: () => null,
resetAfterCommit: () => null,
getChildHostContext: () => null,
shouldSetTextContent: () => null,
createInstance: () => null,
createTextInstance: () => null,
appendInitialChild: () => null,
finalizeInitialChildren: () => null
});

const render = node => {
reconciler.updateContainer(node, reconciler.createContainer());
};

export default render;




reconciler?



あーはいはい!平和をもたらそうとする人ねー!りょうかい~!



リコンサイラ (reconciler)


異なるレンダラ間でコードの一部を共有することでこの課題を解決します。React のこの箇所を “リコンサイラ(reconciler, 差分検出処理)” と呼んでいます。

React公式より抜粋: https://ja.reactjs.org/docs/codebase-overview.html#reconcilers


リコンサイラのおかげで宣言型レンダリング、独自コンポーネント、state、ライフサイクルメソッドがレンダラーのnullみが強くても動いた様子



TODO


  • Lesson component

  • Question component

  • Packaging for npm

その他もろもろ...

インプットしながらやっていく予定

もしこの辺りに知見がある方がいらしたら教えてください!



ありがとうございました🔈