好吧,這個標題有點吸引點擊。有時您需要使用匿名函數作為 props,但它們可能要少得多,謝謝您。但首先,讓我們先描述一下這個問題。
在 Svelte 和 React 這樣的元件庫中,用作元件 props 的匿名函數已經成為一種懶惰的選擇,會威脅到大規模的膨脹。
我看到很多開發者都這麼做:
<button onclick={() => handleSubmit()}>Submit</button>
而不是這個:
<button onclick={handleSubmit}>Submit</button>
每個程式碼區塊實際上都會實現完全相同的結果。唯一的差異是第一個範例中插入了一個匿名函數,它所做的只是呼叫一個不帶參數的命名函數。
你明白為什麼使用匿名方法可能會出現問題嗎?每次呈現此按鈕時,都會建立一個全新的匿名函數並將其保存在記憶體中。如果在同一頁上呈現了十個這樣的函數,那麼記憶體中就會保存十個不同的匿名函數。
現在您可能會說,「好吧,但是我多久會在一個頁面上擁有超過十個或二十個互動元素?」答案是,「你可能認為這是一種邊緣情況,但它出現的次數比你想像的要多。 而且你最好養成良好的習慣,為邊緣情況做好準備!
這可能成為問題的一個主要範例是具有互動功能的較大表格或列表,例如刪除或編輯行或項目。例如,如果您的頁面上有一個資料網格類型的元件,而您的分頁是每頁 100 行,那麼每行建立的任何匿名函數都會出現 100 次。如果您有一個在每一行上執行某些操作的複選框以及“編輯”和“刪除”按鈕,那麼您現在內存中保存了300 個匿名函數,以及命名和聲明的原始3 個函數,由匿名函數呼叫。如果為了效率而進行預渲染之類的欺騙但隱藏下一頁數據,那就更糟了。在這個範例中,記憶體中現在有 600 個匿名函數實例。
好吧,那麼人們為什麼要這樣做呢?
反應性或其他期望的行為
但這些都是邊緣情況,您可以在編碼時根據需要解決。
這可能是最常見的罪魁禍首。它允許您將某種狀態直接傳遞到函數中,因此當您第一次學習 Svelte 或 React 等 UI 庫時,更容易掌握和使用。這可能是為什麼大多數教程將匿名函數顯示為 props 的原因。
這是一個範例(在 Svelte 5 中):
<button onclick={() => handleSubmit()}>Submit</button>
漂亮又乾淨,對吧?但是,如果此頁面上有數百個此按鈕的實例,我們就會遇到潛在的效能問題。我們如何重構它以提高性能?
與程式設計中常見的情況一樣,一個簡單直接的解決方案是確保我們為 EditButton 之類的東西建立單獨的元件,然後我們將 ProductId 範圍限制為該實例。因此,我們不必向處理函數傳遞任何內容,因為它位於一個離散元件內,該元件已經知道 ProductId 是什麼。這就是為什麼程式碼模組化而不是整體化通常會更好。
如果可以的話,您絕對應該先嘗試採用此解決方案。請注意,由於我們的元件被隔離為僅處理一個 ProductId,因此我們不需要該匿名函數。相反,我們的元件函數可以直接處理它。
<button onclick={handleSubmit}>Submit</button>
但有時,由於系統架構或其他原因,我們無法將更新邏輯限制在本地範圍內。為了處理這種情況,我們做了一些事情,是的,有點複雜,而且,我不想這麼說,比發送一個匿名函數作為 prop 稍微不那麼聲明性。但它仍然具有很強的可讀性,並且可以滿足我們不將一堆匿名函數推入記憶體的目的。
它涉及使用 html 元素上的資料屬性來取得您正在處理的事件(例如單擊)。它看起來像這樣:
// EditButton.svelte <script> // productId is sent to this component as a prop let { productId } = $props() </script> const onEditToggle = (productId) => { // Do some stuff with productId... } <button onclick={() => onEditToggle(productId)}> Edit </button>
你看到那裡發生了什麼事嗎?我們將產品 ID 放入 EditButton 內 html 按鈕元素的自訂資料屬性中。當處理函數觸發時,它可以立即從元素的資料屬性中檢索產品 ID。
現在我們只有一個函數,onEditToggle,在記憶體中聲明,其他所有內容都只是透過引用指向它。
我個人的感覺是始終從高度模組化的程式碼開始,以便關鍵資料的傳遞是透過該組件的 props 完成的,而不是讓組件成為整體並必須在內部確定所有這些。這就是我在上面的“更簡單的解決方案”中描述的內容。
如果你絕對做不到,那就採用第二種帶有資料屬性的解決方案。
現在,您可能會說,因為使用匿名函數比處理資料屬性更具可讀性,所以從一開始就更好,所以如果您遇到效能問題,您可以稍後調整它。
我大體上同意這種思路,但在這種情況下,這樣做的併發症有點常見,以至於總是以同樣的方式來做。這樣您就不必考慮是否/何時使用一種方法與另一種方法。它們都有效,如果您發現有這些效能問題,以後將不需要重構。
Svelte 完全有可能在轉譯過程中以某種方式處理這個問題,以某種方式平滑這些匿名函數。我不是 Svelte 運行時或編譯器的專家,無法肯定地說。但我個人認為這是一種更安全的模式,適用於您可能最終使用的任何 JS 庫,因此提前採用是一個更好的習慣。
你覺得怎麼樣?你有反對意見嗎?或者也許可以深入了解 Svelte 在運行時和編譯級別發生的情況,這可能會改變我的觀點?請在評論中告訴我!
以上是停止在 Props 中使用匿名函數!的詳細內容。更多資訊請關注PHP中文網其他相關文章!