好吧,这个标题有点吸引点击。有时您需要使用匿名函数作为 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中文网其他相关文章!