React 的 3 个经验教训,可以让你成为更好的 Svelte 开发人员

2025-06-07

React 的 3 个经验教训,可以让你成为更好的 Svelte 开发人员

Svelte是一个非常棒的 JavaScript 框架,去年备受关注。虽然它自 2016 年底就已问世,但最近才刚刚达到一个临界点,大量开发者热衷于将 Svelte 融入他们的项目。

这意味着我们看到很多新开发人员第一次尝试将Svelte作为他们的第一个框架,甚至更多的开发人员过去曾使用过其他框架。

在这样的时刻,有很多值得兴奋的事情。Svelte为久经考验的前端模式披上了一层闪亮的外衣。然而,我们不应该将此视为一个彻底放弃机会。我们学习了其他框架的最佳实践和模式,它们非常重要,可能还没有融入 Svelte 的语言中,但同样重要。

1. {#each} 上的键

我看到有人讨论迁移到 Svelte 后,循环中突然不再需要键。这当然完全没有根据。Svelte 可能不会像 React 那样让你感到烦扰,但不包含键的影响与React完全相同。Svelte 的实现相当于屏蔽了这些警告。

React为何如此坚持?
将键索引与非键
索引作为键是一种反模式,状态
维护也同样如此。

说实话,这样的例子不胜枚举。这个问题归根结底在于,任何 DOM 可以保存嵌套状态的场景,例如表单、动画、第三方小部件、Web 组件等等,都可能存在状态不一致和状态损坏的情况。幸运的是,在 Svelte 中添加一个键非常简单:

{#each things as thing (thing.id)}
  <Thing name={thing.name}/>
{/each}
Enter fullscreen mode Exit fullscreen mode

当然,并非在所有情况下都需要键,但如果您正在编写通用库和组件,则至少应该支持键控迭代。原因是,一旦您选择不使用键控,就等于选择了所有后代。任何未来的更改或潜在的问题都可能与您甚至没有考虑到的更高层次的事物有关。

每个框架作者都知道这一点,但有时为了方便入门,文档中会轻描淡写。但这却是 React 中无处不在的重要理念,理解它将帮助你成为一名更优秀的 Svelte 开发者。

2. 单值存储无法扩展

这可能非常明显,Svelte 的 Store 机制非常简单且强大。实际上,你可以用它做几乎任何事情。你可以存储单个值,在其中塞入 Reducer,甚至可以是一个状态机。

但是单个 store 是基于一组订阅的。每个监听该 store 的组件都会在 store 发生任何变化时触发更新。这不具备可扩展性。

但拆分到多个 store 最终也会导致复杂的同步。其中存在着一些相互关联的事物,需要协同工作。在一个 store 中更新一个值意味着要更新多个 store 中的值。

在 React 中探索 Flux 架构的早期(2013-14 年),我们见证了从多存储到单存储的演变,以消除过多的同步开销。虽然并非所有数据都需要放在一个存储中,但重要的是要认识到某些数据确实会同时更新,并且嵌套存储也是很自然的。

这正是Redux中诸如选择器和范式化表单,以及 Connect 包装器周围复杂样板代码的动机。或者,这也是VueMobX使用代理来跟踪单个更新的原因。Svelte Stores 并不能单独解决这个问题,时机成熟时重新引入它会带来许多熟悉的样板代码。

有这样一个简单易用的解决方案真是太方便了。大多数响应式框架实际上都内置了响应式原子解决方案,比如Vue 的ref,但有趣的是,考虑到它扩展速度太快,这通常不是它们推荐的 store 方案。

Svelte 对此也不能幸免:
https://github.com/sveltejs/svelte/issues/4079
https://github.com/sveltejs/svelte/issues/3584

因此,在扩展 Svelte 应用并寻求数据架构在性能上的优势时,务必牢记这一点。请做好准备,研究超越简单存储的技术,以确保您的应用程序能够随数据扩展。

3. 不可变接口

React 以其显式的 setter setState、单向流和不可变数据而闻名。但 Svelte 只允许你赋值。

所以,我的意思不是让所有东西都变成不可变的。但我们可以意识到,可变数据结构的挑战在于,一旦它们超出了定义范围,就很难知道会发生什么。经典的例子是:

const someData = { value: 5 };
someFunction(someData);
// do we know this is even true
someData.value === 5;
Enter fullscreen mode Exit fullscreen mode

就我们所知,value它甚至不再是定义好的对象。在系统架构中,你会一次又一次地看到提供带有显式设置器的只读接口的重要性。使用带有调度函数的事件或命令之类的东西。即使是像 MobX 这样的可变响应式数据存储,也建议使用 Actions,并设置严格模式,以防止在预期之外的位置进行写入。在响应式系统中,这一点尤为重要,因为对某个值的更改可能会对应用程序的其他部分产生连锁反应。

幸运的是,Svelte 编译器有一些内置的保护措施。除了使用显式绑定语法外,实际上很难将可写的响应式值传递到模板之外。Svelte 的let变量基本上是与组件绑定的,无法脱离模板,而且 Svelte 的 Stores 是使用显式语法构建的。

所以,这主要归结于理解何时绑定、何时不绑定的影响,以及如何随着应用程序的增长设计存储。通常,显式设置方法或使用事件可以提高应用程序级别的代码清晰度,并改善模块化。它甚至可以很好地解释为什么需要赋值数组来更新它们。因此,即使在 Svelte 中,这也是一个很有用的模式,值得放在工具箱中。

结论

Svelte出色地完成了一项工作,让学习新框架变得轻松有趣。它还提供了所有必要的工具,帮助您实践最佳实践,从而创建可扩展的应用程序。请记住,这就像搬到一个新的国家一样,虽然文化和传统可能略有不同,但相同的自然规律同样适用。

你在其他框架中学习到的工具和模式现在依然重要。虽然我们有时可能不喜欢那些样板代码,但这些东西的存在是有原因的。接受这一点是成为更高层次Svelte开发者的第一步。

文章来源:https://dev.to/this-is-learning/3-lessons-from-react-that-c​​an-make-you-a-better-svelte-developer-23c4
PREV
改进 GitHub 代码评审的 5 个技巧
NEXT
10 个对 Web 开发者有用的 Chrome 扩展程序