Solid.js 就是我理想中的 React

简介: 我大约在三年前开始在工作中使用 React。巧合的是,当时正好是 React Hooks 出来的时候。我当时的项目代码库有很多类组件,总让我觉得很笨重。

我大约在三年前开始在工作中使用 React。巧合的是,当时正好是 React Hooks 出来的时候。我当时的项目代码库有很多类组件,总让我觉得很笨重。

我们来看看下面的例子:一个每秒递增一次的计数器。

image.png

对于一个自动递增的计数器来说要写这么多代码可不算少。更多的模板和仪式意味着出错的可能性更大,开发体验也更差。

Hooks 很漂亮,但是容易出错

当 hooks 出现的时候我非常兴奋。我的计数器可以简化为以下写法:

image.png

等等,这其实是不对的。我们的 useEffect hook 在 count 周围有一个陈旧闭包,因为我们没有把 count 包含在 useEffect 依赖数组中。从依赖数组中省略变量是 React hooks 的一个常见错误,如果你忘记了,有一些 linting 规则会警告你的。

我稍后会回到这个问题上。现在,我们把缺少的 count 变量添加到依赖数组中:

image.png

但现在我们遇到了另一个问题,看看应用程序的运行效果:

image.png

精通 React 的人们可能知道发生了什么事情,因为你每天都在与这种问题作斗争:我们创建了太多的间隔(每次重新运行效果时都会创建一个新间隔,也就是每次我们增加 count 时间隔都会增加)。可以通过几种方式来解决这个问题:

  • 从清除间隔的 useEffect hook 返回一个清理函数
  • 使用 setTimeout 代替 setInterval(还是要使用清理函数)
  • 使用 setCount 的函数形式来避免直接引用当前值

事实上哪种办法都行得通。我们在这里实现最后一个选项:

image.png

我们的计数器修好了!由于依赖数组中没有任何内容,因此我们只创建了一个间隔。由于我们为计数设置器使用了回调函数,因此永远不会在 count 变量上有陈旧闭包。

这是一个人为做出来的例子,但除非你已经使用 React 一段时间,否则它仍然很令人困惑。我们中有许多人每天都会遇到更复杂的情况,即使是最有经验的 React 开发人员也会为之头痛不已。

假# 的响应性

我思考了很多关于 hooks 的事情,想知道为什么它们感觉不太对劲。结果我通过探索 Solid.js 找到了答案。

React hooks 的问题在于 React 并不是真正的响应式设计。如果 linter 知道一个效果(或回调或 memo)hook 何时缺少依赖项,那么为什么框架不能自动检测依赖项并对这些更改做出响应呢?

深入研究 Solid.js

关于 Solid,首先要注意的是它没有尝试重新发明轮子:它看起来很像 React,因为 React 有一些显眼的模式:单向、自上而下的状态;JSX;组件驱动的架构。

如果我们用 Solid 重写 Counter 组件,会这样开始:

image.png

到目前为止我们看到了一个很大的不同点:count 是一个函数。这称为访问器(accessor),它是 Solid 工作机制的重要组成部分。当然,我们这里没有关于按间隔递增 count 的内容,所以下面把它添加进去:

image.png

这肯定行不通,对吧?每次组件渲染时不会设置新的间隔吗?

没有。它就这么正常运行了。

但为什么会这样?好吧,事实证明 Solid 不需要重新运行 Counter 函数来重渲染新的计数。事实上,它根本不需要重新运行 Counter 函数。如果我们在 Counter 函数中添加一个 console.log 语句,就会看到它只运行一次。

image.png

在我们的控制台中,只有一个孤独的日志语句:

image.png

在 Solid 中,除非我们明确要求,否则代码不会多次运行。

但是 hooks 呢?

于是我在 Solid 中解决了 React useEffect hook 的问题,而无需编写看起来像 hooks 的东西。我们可以扩展我们的计数器例子来探索 Solid 效果。

如果我们想在每次计数增加时 console.log count 怎么办?你的第一反应可能是在我们的函数中使用 console.log:

image.png

但这不起作用。请记住,Counter 函数只运行一次!但我们可以使用 Solid 的 createEffect 函数来获得想要的效果:

image.png

这行得通!而且我们甚至不必告诉 Solid,说这个效果取决于 count 变量。这才是真正的响应式设计。如果在 createEffect 函数内部调用了第二个访问器,它也会让效果运行起来。

一些更有趣的 Solid 概念

响应性,而不是生命周期 hooks

如果你已经在 React 领域有一段时间的经验了,那么下面的代码更改可能真的会让你大跌眼镜:

image.png

并且代码仍然是有效的。我们的 count 信号不需要存在于一个组件函数中,依赖它的效果也不需要。一切都只是响应式系统的一部分,“生命周期 hooks”实际上并没有起到太大的作用。

细粒度的 DOM 更新

前面我主要关注的是 Solid 的开发体验(例如更容易编写没有错误的代码),但 Solid 的性能表现也得到了很多赞誉。其强大性能的一个关键来源是它直接与 DOM 交互(无虚拟 DOM)并执行“细粒度”的 DOM 更新。

考虑对我们的计数器进行以下调整:

image.png

运行它会在控制台中获得以下日志:

image.png

换句话说,每秒更新的唯一内容是包含 count 的一小部分 DOM。Solid 甚至没有重新运行同一 div 中较早的 console.log。

小结

在过去的几年里我很喜欢使用 React;在处理实际的 DOM 时,我总感觉它有着正确的抽象级别。话虽如此,我也开始注意到 React hooks 代码经常变得容易出错。我感觉 Solid.js 使用了 React 的许多符合人体工程学的部分,同时最大程度减少了混乱和错误。本文向你展示的是 Solid 的一些让我惊叹的部分,感兴趣的话我建议你查看https://www.solidjs.com并自己探索这个框架

原文链接:https://typeofnan.dev/solid-js-feels-like-what-i-always-wanted-react-to-be/

目录
相关文章
|
4月前
|
前端开发 JavaScript 测试技术
React 中集成 Chart.js 图表库
本文介绍了如何在 React 项目中集成 Chart.js 创建动态图表,涵盖基础概念、安装步骤、代码示例及常见问题解决方法,帮助开发者轻松实现数据可视化。
93 11
|
4月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
84 0
|
4月前
|
资源调度 前端开发 数据可视化
构建高效的数据可视化仪表板:D3.js与React的融合之道
【10月更文挑战第25天】在数据驱动的时代,将复杂的数据集转换为直观、互动式的可视化表示已成为一项至关重要的技能。本文深入探讨了如何结合D3.js的强大可视化功能和React框架的响应式特性来构建高效、动态的数据可视化仪表板。文章首先介绍了D3.js和React的基础知识,然后通过一个实际的项目案例,详细阐述了如何将两者结合使用,并提供了实用的代码示例。无论你是数据科学家、前端开发者还是可视化爱好者,这篇文章都将为你提供宝贵的洞见和实用技能。
121 5
|
4月前
|
监控 前端开发 JavaScript
React 静态网站生成工具 Next.js 入门指南
【10月更文挑战第20天】Next.js 是一个基于 React 的服务器端渲染框架,由 Vercel 开发。本文从基础概念出发,逐步探讨 Next.js 的常见问题、易错点及解决方法,并通过具体代码示例进行说明,帮助开发者快速构建高性能的 Web 应用。
196 10
|
5月前
|
开发框架 前端开发 JavaScript
React、Vue.js 和 Angular主流前端框架和选择指南
在当今的前端开发领域,选择合适的框架对于项目的成功至关重要。本文将介绍几个主流的前端框架——React、Vue.js 和 Angular,探讨它们各自的特点、开发场景、优缺点,并提供选择框架的建议。
115 6
|
6月前
|
前端开发 JavaScript API
React、Vue.js 和 Angular前端三大框架对比与选择
前端框架是用于构建用户界面的工具和库,它提供组件化结构、数据绑定、路由管理和状态管理等功能,帮助开发者高效地创建和维护 web 应用的前端部分。常见的前端框架如 React、Vue.js 和 Angular,能够提高开发效率并促进团队协作。
274 4
|
6月前
|
前端开发 JavaScript 开发者
React 和 Vue.js 框架的区别是什么?
React 和 Vue.js 框架的区别是什么?
|
6月前
|
前端开发 JavaScript 开发者
Express.js与前端框架的集成:React、Vue和Angular的示例与技巧
本文介绍了如何将简洁灵活的Node.js后端框架Express.js与三大流行前端框架——React、Vue及Angular进行集成,以提升开发效率与代码可维护性。文中提供了详细的示例代码和实用技巧,展示了如何利用Express.js处理路由和静态文件服务,同时在React、Vue和Angular中构建用户界面,帮助开发者快速掌握前后端分离的开发方法,实现高效、灵活的Web应用构建。
152 3
|
7月前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
81 0
|
7月前
|
前端开发 JavaScript 开发者
【前端革新力】React与CSS-in-JS完美邂逅:从styled-components到emotion,全面解析样式管理新趋势的实战应用与优势剖析!
【8月更文挑战第31天】CSS-in-JS 作为一种新兴的样式管理方式,近年来在前端社区受到广泛关注。它将样式嵌入 JavaScript,实现了样式与逻辑的高度耦合,提升了开发效率并解决了全局样式污染等问题。本文通过具体代码示例,探讨 CSS-in-JS 在 React 开发中的应用,并分享实践心得。首先介绍了 CSS-in-JS 的基本概念,然后详细展示了如何使用 styled-components 和 emotion 这两个流行库创建样式化组件。
362 0

热门文章

最新文章