ホームページ > 記事 > ウェブフロントエンド > Javascript を使用してリアクティブ ストアを最初から構築する
リアクティブ プログラミングは、データの変更を動的に反映するアプリケーションを作成できる優れたアプローチです。これは、React や Vue などの多くの最新の JavaScript フレームワークの背後にあるコア技術であり、ユーザーのアクションやその他の状態の変化に応じて更新されます。リアクティブの内部にあるものを理解するのは多大な労力のように感じるかもしれませんが、それはフレームワークの「魔法」の抽象化の 1 つであるように感じられます。しかし、小さなリアクティブ システムを自分で構築して、それが実際にどのように機能するかを確認できたらどうでしょうか?
この記事では、JavaScript でシンプルなリアクティブ ストアを最初から構築することで、リアクティブ プログラミングの基本を説明します。依存関係の追跡や自動更新などの主要な概念を最小限の実装で説明します。最終的には、依存関係を自動的に追跡し、状態が変化するたびに更新をトリガーするリアクティブなデータ構造を作成する方法を理解できるはずです。このアプローチは、反応性を理解するのに役立ち、それを自分で実験し、場合によってはプロジェクトに適用するためのツールを提供します。
使用するリアクティブ システムのコア コンポーネントを見てみましょう。
リアクティブ プログラミングの定義は終わったので、使用する Javascript API についても触れておきましょう。
プロキシ: Proxy オブジェクトを使用すると、別のオブジェクトのプロキシを作成でき、基本的な操作 (プロパティ アクセスや割り当てなど) のカスタム動作を定義できます。このコードでは、リアクティブ ストア (状態オブジェクト) を変更に応答させるために使用されます。
Reflect: Reflect API は、インターセプト可能な JavaScript 操作のメソッドを提供します。これは、リアクティブ関数で Reflect.get や Reflect.set などの操作を実行するために使用されます。これにより、プロキシがオブジェクトの元の動作を維持しながら、プロパティへのアクセスと割り当てを処理できるようになります。
Map: Map オブジェクトは、キーと値のペアを保持するコレクションです。キーには任意のデータ型を指定できます。この実装では、各信号に関連付けられた依存関係を追跡する dependencyMap を作成するために使用されます。
さて、初期状態がどのようになるかを定義してみましょう:
// Let's define a Map object to track our dependencies const dependencyTrackerMap = new Map(); // The activeEffect variable will hold the currently executing // effect function. // It will be set when an effect is run and will be used // to track which effects depend on specific reactive properties. let activeEffect = null // This function will make an object reactive function reactive(target) { return new Proxy(target, { get(obj, prop) { trackDependency(prop); // Track dependency return Reflect.get(obj, prop); }, set(obj, prop, value) { const result = Reflect.set(obj, prop, value); triggerDependency(prop); // Trigger reactions return result; } }); } // the effect function will register reactive functions function effect(fn) { activeEffect = fn; fn(); // Run the function once to register dependencies activeEffect = null; } // this function will track dependencies function trackDependency(key) { if (activeEffect) { if (!dependencyTrackerMap.has(key)) { dependencyTrackerMap.set(key, new Set()); } dependencyTrackerMap.get(key).add(activeEffect); } } // this function will trigger dependencies function triggerDependency(key) { const deps = dependencyTrackerMap.get(key); if (deps) { deps.forEach(effect => effect()); } } // This will create a reactive object with an initial state // count and message here are signals const state = reactive({ count: 0, message: "Hello" });
それで、私たちがやったことは次のとおりです:
次に、コールバックを使用してエフェクトを作成し、それをトリガーしてみましょう:
// Let's define a Map object to track our dependencies const dependencyTrackerMap = new Map(); // The activeEffect variable will hold the currently executing // effect function. // It will be set when an effect is run and will be used // to track which effects depend on specific reactive properties. let activeEffect = null // This function will make an object reactive function reactive(target) { return new Proxy(target, { get(obj, prop) { trackDependency(prop); // Track dependency return Reflect.get(obj, prop); }, set(obj, prop, value) { const result = Reflect.set(obj, prop, value); triggerDependency(prop); // Trigger reactions return result; } }); } // the effect function will register reactive functions function effect(fn) { activeEffect = fn; fn(); // Run the function once to register dependencies activeEffect = null; } // this function will track dependencies function trackDependency(key) { if (activeEffect) { if (!dependencyTrackerMap.has(key)) { dependencyTrackerMap.set(key, new Set()); } dependencyTrackerMap.get(key).add(activeEffect); } } // this function will trigger dependencies function triggerDependency(key) { const deps = dependencyTrackerMap.get(key); if (deps) { deps.forEach(effect => effect()); } } // This will create a reactive object with an initial state // count and message here are signals const state = reactive({ count: 0, message: "Hello" });
作成した状態を更新しようとすると、コンソール ログがトリガーされます:
//We are using state from the previous snippet: effect(() => { console.log(Count has changed: ${state.count}); }); effect(() => { console.log("Message has changed"); console.log(The new message is: ${state.message}); });
依存関係がトリガーされたときに何が起こるかを少し視覚的に示します。
この記事では、JavaScript で基本的なリアクティブ システムを作成し、データの変更に応じた自動更新 (または副作用) を可能にする方法を検討しました。この実装は、フレームワーク「マジック」の一部であるリアクティブ プログラミングの概念への入門として機能します。さらに、Proxy API と Reflect API が何をするのかを学び、それらと Map オブジェクトを使用しました。
要約すると、このリアクティブ システムは依存関係を管理し、状態が変化したときにエフェクトを自動的に更新します。特定のリアクティブ プロパティに依存する関数を登録すると、システムはどの関数がどのプロパティに依存するかを追跡し、必要に応じて再実行します。このアプローチにより、コードを追加することなく状態の変更が自動的に UI に反映される応答性の高いアプリケーションを作成でき、開発者のエクスペリエンスが向上し、データ処理がより簡単かつ効率的になります。
以上がJavascript を使用してリアクティブ ストアを最初から構築するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。