反應式程式設計是一種巧妙的方法,可讓您建立動態反映資料變更的應用程式。它是 React 和 Vue 等許多現代 JavaScript 框架背後的核心技術 - 它會根據用戶操作或其他狀態變化進行更新。理解反應性背後的內容可能感覺工作量太大,感覺就像框架所針對的「神奇」抽象之一。但是,如果您可以自己建立一個小型反應式系統來看看它是如何運作的呢?
本文將透過使用 JavaScript 從頭開始建立一個簡單的反應式儲存來介紹反應式程式設計的基礎知識。我們將以最小的實作方式介紹關鍵概念,包括依賴項追蹤和自動更新。最後,您應該能夠了解如何建立反應式資料結構,以便在狀態變更時自動追蹤依賴關係並觸發更新。這種方法將幫助您理解反應性,並為您提供自行實驗的工具,並可能將其應用到您的專案中。
讓我們開始看看我們將要使用的反應式系統的核心組件:
現在我們已經了解了響應式程式定義,讓我們也提一下我們將要使用的 Javascript API:
Proxy: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 和 Reflect API 的作用並使用了它們,以及 Map 物件。
總之,這個反應式系統管理依賴關係並在狀態變化時自動更新效果。透過註冊依賴特定反應屬性的函數,系統可以追蹤哪些函數依賴哪些屬性,並在需要時重新運行它們。這種方法允許創建響應式應用程序,其中狀態變更會自動反映在 UI 中,無需額外程式碼,從而改善開發人員體驗並使資料處理更輕鬆、更有效率。
以上是使用 Javascript 從頭開始建立反應式商店的詳細內容。更多資訊請關注PHP中文網其他相關文章!