以下に日本語訳を示します。
これはカスタムReactレンダラーを作成するための実験的なパッケージです。
このAPIはReact、React Native、React DOMほど安定しておらず、一般的なバージョニングスキームに従っていません。
自己責任で使用してください。
const Reconciler = require('react-reconciler');
const HostConfig = {
// いくつかのメソッドをここに実装する必要があります。
// 詳細と例については、以下を参照してください。
};
const MyRenderer = Reconciler(HostConfig);
const RendererPublicAPI = {
render(element, container, callback) {
// MyRenderer.updateContainer()を呼び出して、ルートの変更をスケジュールします。
// 実際の例については、ReactDOM、React Native、またはReact ARTを参照してください。
}
};
module.exports = RendererPublicAPI;
"host config" は、あなたが提供する必要があるオブジェクトであり、"host" 環境 (例えば、DOM、canvas、console、またはあなたのレンダリングターゲット) で何かを起こす方法を記述します。これは次のようになります。
const HostConfig = {
createInstance(type, props) {
// 例: DOM レンダラーは DOM ノードを返します
},
// ...
supportsMutation: true, // ノードのミューテーションによって動作します
appendChild(parent, child) {
// 例: DOM レンダラーはここで .appendChild() を呼び出します
},
// ...
};
非常にシンプルなカスタムレンダラーの作成に関する入門については、以下の一連の記事を確認してください。
サポートされているメソッドの完全なリストはこちらにあります。それらのシグネチャについては、以下の具体的な例を参照することをお勧めします。
React リポジトリには、いくつかのレンダラーが含まれています。それぞれに独自のホスト構成があります。
React リポジトリの例は、サードパーティのレンダラーとは少し異なる方法で宣言されています。具体的には、上記の HostConfig
オブジェクトは明示的に宣言されず、代わりにコード内の モジュール です。ただし、そのエクスポートは、コードで宣言する必要がある HostConfig
オブジェクトのプロパティに直接対応しています。
これらのリンクが壊れている場合は、問題を報告してください。修正します。API はまだ進化しているため、意図的に最新バージョンにリンクしています。さらに質問がある場合は、問題を報告してください。できる限りお手伝いします。
現時点では、ホスト構成はリリース間で非常に頻繁に変更されるため、すべてのAPIの詳細を文書化することを約束できません。以下のドキュメントは、APIの保証ではなく、最善を尽くすという精神で提供されています。あまり頻繁に変更されない部分に焦点を当てています。これは、React自体の急速な開発の必要性と、カスタムレンダラーコミュニティにとってのこのパッケージの有用性との間のバランスをとる妥協案です。最新の安定版の動作と一致しない部分や古い部分に気付いた場合は、問題を報告するかプルリクエストを送信してください。ただし、応答には時間がかかる場合があります。
reconciler には、ミューテーションモードとパーシステントモードの 2 つのモードがあります。どちらかを指定する必要があります。
ターゲットプラットフォームが DOM に似ており、appendChild
、removeChild
などのようなメソッドを持っている場合は、ミューテーションモードを使用する必要があります。これは、React DOM、React ART、および従来の React Native レンダラーで使用されるのと同じモードです。
const HostConfig = {
// ...
supportsMutation: true,
// ...
}
ターゲットプラットフォームがイミュータブルなツリーを持っている場合は、代わりにパーシステントモードを使用する必要があります。そのモードでは、既存のノードは変更されず、代わりにすべての変更が親ツリーを複製し、ルートで親ツリー全体を置き換えます。"Fabric" というコードネームの新しい React Native レンダラーで使用されるモードです。
const HostConfig = {
// ...
supportsPersistence: true,
// ...
}
モードに応じて、reconciler はホスト構成で異なるメソッドを呼び出します。
どちらが必要かわからない場合は、おそらくミューテーションモードが必要です。
このメソッドは、新しく作成されたノードを返す必要があります。たとえば、DOM レンダラーはここで document.createElement(type)
を呼び出し、props
からプロパティを設定します。
rootContainer
を使用して、そのツリーに関連付けられているルートコンテナにアクセスできます。たとえば、DOM レンダラーでは、これはルートが属する正しい document
参照を取得するのに役立ちます。
hostContext
パラメーターを使用すると、ツリー内の現在の場所に関する情報を追跡できます。詳細については、以下の getChildHostContext
を参照してください。
internalHandle
データ構造は、不透明であることを意図しています。ルールを曲げて内部フィールドに依存する場合は、バージョン間で大幅に変更される可能性があることに注意してください。そこから読み取ることで追加のメンテナンスリスクを負い、そこに何かを書き込むとすべての保証を放棄することになります。
このメソッドはレンダーフェーズで発生します。返却する前に、作成したばかりのノードを変更できます (そして通常は変更する必要があります) が、他のノードを変更してはなりません。親ツリーにイベントハンドラーを登録してはなりません。これは、インスタンスが作成されたからといって、必ずしもツリーに配置されるとは限らないためです。未使用のままになり、後で GC によって収集される可能性があります。インスタンスが確実にツリー内にあるときに何かを実行する必要がある場合は、代わりに commitMount
を参照してください。
createInstance
と同じですが、テキストノード用です。レンダラーがテキストノードをサポートしていない場合は、ここで例外をスローできます。
このメソッドは parentInstance
を変更し、子をその子のリストに追加する必要があります。たとえば、DOM では、これは parentInstance.appendChild(child)
呼び出しに変換されます。
このメソッドはレンダーフェーズで発生します。parentInstance
と child
は変更できますが、他のノードは変更してはなりません。ツリーがまだ構築中であり、画面上の実際のツリーに接続されていない間に呼び出されます。
このメソッドでは、instance
に対していくつかの最終的な変更を実行できます。createInstance
とは異なり、finalizeInitialChildren
が呼び出されるまでに、すべての初期の子はすでに instance
に追加されていますが、インスタンス自体はまだ画面上のツリーに接続されていません。
このメソッドはレンダーフェーズで発生します。instance
は変更できますが、他のノードは変更してはなりません。ツリーがまだ構築中であり、画面上の実際のツリーに接続されていない間に呼び出されます。
このメソッドには 2 番目の目的があります。ノードが画面上のツリーに接続されたときに実行する必要がある作業があるかどうかを指定できます。true
を返すと、インスタンスは後で commitMount
呼び出しを受け取ります。以下のドキュメントを参照してください。
ここで何もしたくない場合は、false
を返す必要があります。
一部のターゲットプラットフォームでは、テキストノードを手動で作成せずに、インスタンスのテキストコンテンツを設定できます。たとえば、DOM では、テキストノードを作成して追加する代わりに、node.textContent
を設定できます。
このメソッドから true
を返すと、React はこのノードの子がテキストであると想定し、それらのノードを作成しません。代わりに、createInstance
中にそのテキストを入力したことに依存します。これはパフォーマンスの最適化です。たとえば、DOM レンダラーは、type
が既知のテキストのみの親 ( 'textarea'
など) である場合、または props.children
が 'string'
型である場合にのみ true
を返します。true
を返す場合は、resetTextContent
も実装する必要があります。
ここで何もしたくない場合は、false
を返す必要があります。
このメソッドはレンダーフェーズで発生します。そこからツリーを変更しないでください。
このメソッドを使用すると、ツリーのルートから初期ホストコンテキストを返すことができます。ホストコンテキストの説明については、getChildHostContext
を参照してください。
ホストコンテキストを使用しない場合は、null
を返すことができます。
このメソッドはレンダーフェーズで発生します。そこからツリーを変更しないでください。
ホストコンテキストを使用すると、ツリー内のどこにいるかに関する情報を追跡できるため、createInstance
内で hostContext
パラメーターとして使用できます。たとえば、DOM レンダラーはこれを使用して、HTML ツリー内にあるか SVG ツリー内にあるかを追跡します。これは、createInstance
の実装がそれらで異なる必要があるためです。
この type
のノードが、渡したいコンテキストに影響を与えない場合は、parentHostContext
を返すことができます。または、渡したい情報を表す任意のカスタムオブジェクトを返すこともできます。
ここで何もしたくない場合は、parentHostContext
を返します。
このメソッドはレンダーフェーズで発生します。そこからツリーを変更しないでください。
ref として公開されるオブジェクトを決定します。おそらく instance
自体を返したいでしょう。しかし、場合によっては、その一部のみを公開する方が理にかなっている場合があります。
ここで何もしたくない場合は、instance
を返します。
このメソッドを使用すると、React が画面上のツリーに変更を加える前に、いくつかの情報を保存できます。たとえば、DOM レンダラーは現在のテキスト選択範囲を保存して、後で復元できるようにします。このメソッドは resetAfterCommit
と対になっています。
ここで何もしたくない場合でも、そこから null
を返す必要があります。
以下に日本語訳を提示します。
このメソッドは、React がツリーのミューテーションを実行した直後に呼び出されます。prepareForCommit
で保存したものを復元するために使用できます (たとえば、テキストの選択範囲など)。
空のままにしておくこともできます。
このメソッドは、ポータルのターゲットとして使用されるコンテナに対して呼び出されます。通常は空のままにしておくことができます。
これを setTimeout
または環境内の同等のものにプロキシできます。
これを clearTimeout
または環境内の同等のものにプロキシできます。
これは、有効なタイムアウト ID になりえないものに設定する必要があるプロパティ (関数ではない) です。たとえば、-1
に設定できます。
レンダラーが scheduleMicrotask
をサポートしていることを示すには、これを true に設定します。React DOM では、ディスクリートイベント実装の一部としてマイクロタスクを使用します。レンダラーがこれをサポートする必要があるかどうかわからない場合は、おそらくサポートする必要があります。scheduleMicrotask
を実装しないオプションが存在するのは、React Native のように、ユーザーイベントをより細かく制御できるプラットフォームが、異なるメカニズムを使用できるようにするためです。
任意。これを queueMicrotask
または環境内の同等のものにプロキシできます。
これは、レンダラーがページ上のメインのレンダラーである場合に true
に設定する必要があるプロパティ (関数ではない) です。たとえば、ターミナル用のレンダラーを作成している場合は、これを true
に設定するのが理にかなっていますが、レンダラーが React DOM やその他の既存のレンダラーの 上に 使用される場合は、false
に設定します。
このメソッドを実装するには、特別な react-reconciler/constants
エントリポイントで利用可能な定数がいくつか必要になります。
import {
DiscreteEventPriority,
ContinuousEventPriority,
DefaultEventPriority,
} from 'react-reconciler/constants';
const HostConfig = {
// ...
getCurrentEventPriority() {
return DefaultEventPriority;
},
// ...
}
const MyRenderer = Reconciler(HostConfig);
返す定数は、現在処理されているイベント (もしあれば) によって異なります。(ブラウザでは、window.event && window.event.type
を使用してこれを確認できます)。
-
離散イベント: アクティブなイベントが ユーザーによって直接引き起こされ (マウスやキーボードイベントなど)、 シーケンス内の各イベントが意図的である (例:
click
) 場合は、DiscreteEventPriority
を返します。これは、バックグラウンド作業を中断する必要があり、時間をまたいでバッチ処理できないことを React に伝えます。 -
連続イベント: アクティブなイベントが ユーザーによって直接引き起こされる が、 ユーザーがシーケンス内の個々のイベントを区別できない (例:
mouseover
) 場合は、ContinuousEventPriority
を返します。これは、バックグラウンド作業を中断する必要があるが、時間をまたいでバッチ処理できることを React に伝えます。 -
その他のイベント / アクティブなイベントがない場合: その他のすべての場合は、
DefaultEventPriority
を返します。これは、このイベントがバックグラウンド作業と見なされ、インタラクティブなイベントが優先されることを React に伝えます。
ReactFiberConfigDOM.js
の getCurrentEventPriority()
実装を参照して、実装例を確認できます。
React をミューテーションモードで使用している場合 (おそらくそうでしょう)、さらにいくつかのメソッドを実装する必要があります。
このメソッドは parentInstance
を変更し、子をその子のリストに追加する必要があります。たとえば、DOM では、これは parentInstance.appendChild(child)
呼び出しに変換されます。
このメソッドは現在コミットフェーズで実行されますが、それでも他のノードを変更しないでください。ノードが確実に可視ツリーに接続されているときに追加の作業を行う必要がある場合は、commitMount
を参照してください。
appendChild
と同じですが、ノードがルートコンテナにアタッチされる場合です。これは、ルートへのアタッチの実装が少し異なる場合、またはルートコンテナノードがツリーの残りの部分とは異なるタイプである場合に役立ちます。
このメソッドは parentInstance
を変更し、child
を beforeChild
の前に、その子のリストに配置する必要があります。たとえば、DOM では、これは parentInstance.insertBefore(child, beforeChild)
呼び出しに変換されます。
React はこのメソッドを挿入とノードの並べ替えの両方に使用することに注意してください。DOM と同様に、既存の子を再配置するために insertBefore
を呼び出すことができると想定されています。ツリーの他の部分を変更しないでください。
insertBefore
と同じですが、ノードがルートコンテナにアタッチされる場合です。これは、ルートへのアタッチの実装が少し異なる場合、またはルートコンテナノードがツリーの残りの部分とは異なるタイプである場合に役立ちます。
以下に日本語訳を示します。
このメソッドは parentInstance
を変更して、child
をその子のリストから削除する必要があります。
React は、削除される最上位のノードに対してのみこれを呼び出します。ガベージコレクションがサブツリー全体を処理することが期待されます。このメソッド内で子ツリーを走査する必要はありません。
removeChild
と同じですが、ノードがルートコンテナからデタッチされる場合です。これは、ルートへのアタッチの実装が少し異なる場合、またはルートコンテナノードがツリーの残りの部分とは異なるタイプである場合に役立ちます。
以前の props に対して shouldSetTextContent
から true
を返したが、次の props に対して shouldSetTextContent
から false
を返した場合、React はこのメソッドを呼び出して、手動で管理していたテキストコンテンツをクリアできるようにします。たとえば、DOM では、node.textContent = ''
を設定できます。
shouldSetTextContent
から true
を返さない場合は、空のままにしておくことができます。
このメソッドは textInstance
を変更し、そのテキストコンテンツを nextText
に更新する必要があります。
ここで、textInstance
は createTextInstance
によって作成されたノードです。
このメソッドは、このインスタンスに対して finalizeInitialChildren
から true
を返した場合にのみ呼び出されます。
これにより、ノードが初めて画面上のツリーに実際にアタッチされた後に追加の作業を行うことができます。たとえば、DOM レンダラーはこれを使用して、autoFocus
属性を持つノードにフォーカスをトリガーします。
commitMount
は removeChild
と 1 対 1 で対応していないことに注意してください。removeChild
は削除される最上位のノードに対してのみ呼び出されるためです。このため、理想的には commitMount
は instance
自体以外のノードを変更すべきではありません。たとえば、上位のノードにイベントを登録する場合、removeChild
でツリーを走査してそれらをクリーンアップするのはあなたの責任になりますが、これは理想的ではありません。
internalHandle
データ構造は、不透明であることを意図しています。ルールを曲げて内部フィールドに依存する場合は、バージョン間で大幅に変更される可能性があることに注意してください。そこから読み取ることで追加のメンテナンスリスクを負い、そこに何かを書き込むとすべての保証を放棄することになります。
finalizeInitialChildren
から true
を返さない場合は、空のままにしておくことができます。
このメソッドは、instance
を nextProps
に一致するように変更する必要があります。
internalHandle
データ構造は、不透明であることを意図しています。ルールを曲げて内部フィールドに依存する場合は、バージョン間で大幅に変更される可能性があることに注意してください。そこから読み取ることで追加のメンテナンスリスクを負い、そこに何かを書き込むとすべての保証を放棄することになります。
このメソッドは、instance
をツリーから削除せずに非表示にする必要があります。たとえば、視覚的なスタイルを適用して非表示にすることができます。Suspense によって、フォールバックが表示されている間、ツリーを非表示にするために使用されます。
hideInstance
と同じですが、createTextInstance
によって作成されたノード用です。
このメソッドは、instance
を表示し、hideInstance
が行ったことを元に戻す必要があります。
unhideInstance
と同じですが、createTextInstance
によって作成されたノード用です。
このメソッドは、container
ルートノードを変更し、そこからすべての子を削除する必要があります。
以下に日本語訳を示します。
このメソッドは、ホストコンポーネントのタイプと props が、更新をコミットする前に完了する必要がある何らかの読み込みプロセスを必要とするかどうかを判断するために、レンダー中に呼び出されます。
このメソッドは、ホストコンポーネントのタイプと props がコミットを中断する可能性がある場合に、レンダー中に呼び出されることがあります。これは、中断されたコミットの期間を短縮する可能性のある作業を開始するために使用できます。
このメソッドは、コミットフェーズの直前に呼び出されます。このコミットを中断する可能性のあるホストコンポーネントが評価されてコミットを中断する必要があるかどうかを判断する際に、必要な状態を設定するために使用します。
このメソッドは、コミットを中断する可能性があることを示した各ホストコンポーネントに対して、startSuspendingCommit
の後に呼び出されます。
このメソッドは、すべての suspendInstance
呼び出しが完了した後に呼び出されます。
コミットをすぐに実行できる場合は、null
を返します。
コミットを中断する必要がある場合は、(initiateCommit: Function) => Function
を返します。このコールバックへの引数は、呼び出されたときにコミットを開始します。戻り値は、Reconciler がコミットを中止するために使用できるキャンセル関数です。
ミューテーションモードの代わりにパーシステントモードを使用する場合は、「コアメソッド」は引き続き必要です。ただし、上記のミューテーションメソッドの代わりに、ノードのクローン作成とルートレベルでのノードの置き換えを実行する別のメソッドセットを実装します。それらのリストは、このファイルにリストされている「パーシステンス」セクションにあります。ヘルプが必要な場合は、問題を報告してください。
オプションで、初期レンダリング中にツリーを最初から作成する代わりに、既存のツリーに「アタッチ」するハイドレーションを実装できます。たとえば、DOM レンダラーはこれを使用して HTML マークアップにアタッチします。
ハイドレーションをサポートするには、supportsHydration: true
を宣言し、このファイルにリストされている「ハイドレーション」セクションのメソッドを実装する必要があります。ヘルプが必要な場合は、問題を報告してください。
https://github.com/facebook/react/tree/062fb31155e42b6997a35b97180055814471620c/packages/react-reconciler
ここから翻訳