初期値ロードと内部状態管理を簡素化した Lexical エディタのビルドライフサイクル改修
Lexical エディタは初期値のロードと内部状態の追跡ロジックを見直し、#loadInitialValue を用いた初期化、冗長な valueLoaded フラグの除去、internalFormValue の変数数を削減し、value と toString() のゲッターで editor.read を必ず実行して更新を確実に反映させるようになりました。
背景
これまで #valueLoaded フラグでエディタの初期値ロード状態を追跡していたものの、エディタ自体が初期状態で値を保持するため重複した管理となっていました。さらに internalFormValue の追跡は three つの変数・セッターで実装され、状態の一貫性を保つために余計なコードが増えていました。これらの冗長性はコードベースの保守性を低下させ、不要なメモリ保持につながっていました。PR #1085 では、初期化プロセスを簡素化しつつ動作を変えない形でリファクタリングを行いました。
技術的な変更
初期値ロードの統合
#loadInitialValue が $initialEditorState に渡され、エディタが生成時に自動的に初期値を取り込むようになりました。これに伴い #valueLoaded フラグは削除され、disconnectedCallback での条件分岐も省略されました。
@@
- #valueLoaded = false
+ // #valueLoaded removed – editor loads its own value
内部フォーム値の追跡を二つに削減
#previousInternalFormValue が新たに導入され、#initialValue と合わせて二つのプライベートプロパティで状態を管理します。#setInternalFormValue は internals.setFormValue の呼び出しだけに集中し、余計な変数は廃止されました。
@@
- #initialValue = ""
+ #initialValue = ""
+ #previousInternalFormValue = null
@@
- if (this.#valueLoaded) {
- this.valueBeforeDisconnect = this.value
- } else {
- this.valueBeforeDisconnect = null
- }
- this.#valueLoaded = false
+ this.#previousInternalFormValue = null
+ this.valueBeforeDisconnect = this.value
+ this.#clearCachedValues()
ゲッターでの強制更新
value と toString() のゲッターは editor.read を経由して最新のエディタ状態を取得し、キャッシュが未初期化の場合にだけ計算を行うように変更されました。toString() では null 合体代入演算子 (??=) を用いて一度だけ計算結果を保持します。
@@
- if (this.cachedStringValue == null) {
- this.editor?.getEditorState().read(() => {
- this.cachedStringValue = $getReadableTextContent($getRoot())
- })
- }
-
- return this.cachedStringValue
+ return this.cachedStringValue ??= this.editor?.read(() => {
+ return $getReadableTextContent($getRoot())
+ })
アダプタ用ディスパッチフラグの明確化
#editorInitializedDispatched の設定位置が変更され、アダプタ側で使用されることを明示的に示すコメントが追加されました。これによりフラグの目的がコードリーダーにとって明瞭になります。
@@
- #editorInitializedDispatched = false
+ // true when adapter dispatches editorInitialized
+ #editorInitializedDispatched = false
設計判断
この改修は 状態追跡の最小化 を設計指針に据え、エディタ自身が保持するデータと重複しないプライベートプロパティだけを残す選択をしています。#valueLoaded の除去は、エディタの内部ロジックに依存する形にシフトしたことで、外部からの余計なフラグ管理を不要にしました。toString() の実装変更は 遅延評価+キャッシュ パターンを採用し、頻繁な文字列化によるコスト増を防ぎつつ、最新状態の取得を保証します。全体として、コードの可読性とメンテナンス性が向上し、動作上の後方互換性は維持されたまま、ライフサイクル管理がシンプルになりました。
まとめ
PR #1085 は、Lexical エディタの初期化と内部状態管理を冗長なフラグや変数から解放し、editor.read による確実な更新取得とキャッシュ戦略で挙動を統一しました。これにより、エディタのビルドライフサイクルが簡潔になり、将来的な拡張や保守が容易になると同時に、既存の機能動作はそのまま保持されます。