首頁 > web前端 > js教程 > 停止在 Props 中使用匿名函數!

停止在 Props 中使用匿名函數!

Mary-Kate Olsen
發布: 2025-01-01 11:13:09
原創
863 人瀏覽過

Quit Using Anonymous Functions in Props!

好吧,這個標題有點吸引點擊。有時您需要使用匿名函數作為 props,但它們可能要少得多,謝謝您。但首先,讓我們先描述一下這個問題。

匿名函數作為 Props

在 Svelte 和 React 這樣的元件庫中,用作元件 props 的匿名函數已經成為一種懶惰的選擇,會威脅到大規模的膨脹。

我看到很多開發者都這麼做:

<button onclick={() => handleSubmit()}>Submit</button>
登入後複製
登入後複製

而不是這個:

<button onclick={handleSubmit}>Submit</button>
登入後複製
登入後複製

每個程式碼區塊實際上都會實現完全相同的結果。唯一的差異是第一個範例中插入了一個匿名函數,它所做的只是呼叫一個不帶參數的命名函數。

你明白為什麼使用匿名方法可能會出現問題嗎?每次呈現此按鈕時,都會建立一個全新的匿名函數並將其保存在記憶體中。如果在同一頁上呈現了十個這樣的函數,那麼記憶體中就會保存十個不同的匿名函數。

現在您可能會說,「好吧,但是我多久會在一個頁面上擁有超過十個或二十個互動元素?」答案是,「你可能認為這是一種邊緣情況,但它出現的次數比你想像的要多。 而且你最好養成良好的習慣,為邊緣情況做好準備!

這可能成為問題的一個主要範例是具有互動功能的較大表格或列表,例如刪除或編輯行或項目。例如,如果您的頁面上有一個資料網格類型的元件,而您的分頁是每頁 100 行,那麼每行建立的任何匿名函數都會出現 100 次。如果您有一個在每一行上執行某些操作的複選框以及“編輯”和“刪除”按鈕,那麼您現在內存中保存了300 個匿名函數,以及命名和聲明的原始3 個函數,由匿名函數呼叫。

如果為了效率而進行預渲染之類的欺騙但隱藏下一頁數據,那就更糟了。在這個範例中,記憶體中現在有 600 個匿名函數實例。

好吧,那麼人們為什麼要這樣做呢?

我至少可以想到這個習慣如此普遍和根深蒂固的兩個原因。

反應性或其他期望的行為

至少在 Svelte 中,有時您需要這樣做以確保函數被響應式呼叫。可能還有其他類型的情況需要您這樣做才能讓您的邏輯按預期工作,儘管我已經使用 React 幾年了,但我敢打賭該庫中也有一些類似的示例。

但這些都是邊緣情況,您可以在編碼時根據需要解決。

簡化函數參數的傳遞

這可能是最常見的罪魁禍首。它允許您將某種狀態直接傳遞到函數中,因此當您第一次學習 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中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板