过去很长一段时间,前端框架们都在往响应式的方向发展。大家都在基于 signal 实现自己的底层。这种趋势看上去非常火热,给人一种前端框架不往这个方向发展就落后了一样。同时又由于 React hooks 的深远影响,函数式 + 响应式成为了不少前端心中最理想的前端框架模样。Solid 成为了这种模式里最具代表性的框架。
但是,尽管如此,我依然对他保持一种不太愿意接纳的态度,并不是说我对 solid 不熟悉,或者抗拒接受新的知识,其根本原因,还是在语法设计上的问题。基于响应式能实现细粒度更新,抛去虚拟 DOM 的 diff 成本,性能能够得到很大的提升。这种设想其实非常美好,但是,在语法设计上会面临巨大的挑战。
Solid.js
我们来观察并分析一下 solid.js 在语法设计上存在的问题。
function Counter() {
const [count, setCount] = createSignal(0)
return <div onClick={() => setCount(count() + 1)}>
Count: {count()}
</div>
}
在这个案例中,我们可以使用 createSignal 创建一个响应式数据。这里的问题就在于,返回的响应式数据 count 他不是一个数据,而是一个获取数据的 getter 方法。因为底层基于 Proxy 来实现,我们需要监听到数据的变化,那么就需要借助 Proxy 中的 getter 方法来实现,因此反馈到语法上,count 就只能是一个函数。
当我们想要将其渲染到 JSX 中时,在 solid 中就将其设计成 {count()}。这里设计成 count() 是沿用了 React 对于 JSX 的理解,想要传入一个值给 JSX。
当我们在点击事件中使用该响应式数据时
// 堆代码 duidaima.com
setCount(count() + 1);
如果你要精准理解 count(),那么理解成本就有点高了,这里的 count() 执行,表达了两层含义。初始化时,count() 表示会隐式的收集依赖。在跟踪范围内,调用 getter 会导致调用 getter 的函数依赖于对应的 signal。当 signal 更新时,这些依赖都会被重新执行。
更新时是依赖重新执行,不只是 count() 重新执行。许多人理解成 count 重新执行,那么在语义上会有更进一步的冲突
例如:
const double_count = () => count() * 2
// 或者在 jsx 中
<div>count: {count()}</div>
更新时,当我们通过点击等行为触发更新,此时当我们使用 count(),则只是简单的计算出 count 当前的值
setCount(count() + 1);
这里其实就是语法设计上的冲突问题。同样的函数执行,由于编译手段的强势侵入,在不同的场景里表达了不同的含义。其实 solid.js 的开发团队也希望 count 就像是直观表达的那样,他不是一个 getter,而就是直接是一个值,因此就有类似于如下的语法设计
// 这个时候就变得正常了
setCount((count) => count + 1);
但是很显然,如果直接完全像 React 那样符合直觉的语法设计,响应式的能力就得不到保证了。因此这是拥抱响应式不得不做出的牺牲。Solid 的这个语法割裂,在组件传参的语法设计中,表现得尤为明显。
例如你看下面这段代码,令人意外的是,props.msg 是可以具备响应性的,当我还不熟悉 Solid 的时候直接大吃一惊。
function Message(props: Props) {
return <div>
<h1>
hello, this message is: {props.msg}
</h1>
<Child />
</div>
}
这是拥抱响应式的无奈之举。因为在组件传参的时候,其实可能存在两种类型,一种类型是普通数据,例如
<Message msg='hello world' />
而另外一种,就是响应性数据,例如
<Message msg={msg()} />
如果我希望一个字段,他可以传普通类型、也可以传响应性类型,那么问题就来了,子元素内部如何判断父组件到底会传什么类型过来呢?solid 的解决方案就是,只允许在父组件传参时,这样写 {msg()}。下面这种写法就会报错
<Message msg={msg} />
![](data:image/png;base64,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)
这样做的好处就是 solid 可以利用编译手段去识别 msg() 然后深入子组件内部做依赖收集,从而让子组件内部不需要做额外的判断。但是付出的代价就是语法割裂更严重了。
除此之外,正因为有黑科技的强势侵入,因此 solid 中的 JSX 与 React 中的 JSX 表现并完全不一致,也不能按照常规的表达式去理解。语法的割裂是我不愿意拥抱 Solid 的主要原因。
Leptos
让我们来看看 rust 生态中,同样是基于 signal 来实现的响应式框架 Leptos 是如何在语法设计上解决 solid 的割裂问题的。首先,一个非常巧妙的设计就是,在 rsx 中,状态传入的括号中,直接接收的就是一个函数
#[component]
fn App() -> impl IntoView {
let (count, set_count) = create_signal(0);
view! {
<div>{count}</div>
}
)
这里类似于 React 的 render props 。这样看着就非常的舒服。因为声明的 count 是一个函数,模板渲染中需要的也是一个函数,语法表现就很一致,按照这个设计,我们就可以不用写 count() 了。这个小的语法设计细节的调整,让整个语法都变得更加一致。
当我们更新时
set_count.update(|count| *count += 1)
当我们要往子组件中传递参数时
<ProgressBar progress=count />
当语法规则发生一些简单的调整,我们会发现,在大多数情况下,count 的使用都保持了一致性,而不是像 solid 那样在不同的场景之下有不同的行为。当然,如果我们要在逻辑中获取到 count 的值时,仍然需要使用 count() 来达到目的。不过这在语义上是没有冲突的。
let double = move || count() * 2;
与 solid 一样,这段代码类似于计算属性,这个匿名函数也会被收集成为一个依赖,从而让 double 也具备响应性。当我们往组件内部传参数时,rust 可以通过定义参数宏来接收和设置参数的类型、默认值等
#[component]
pub fn ProgressBar(
#[prop(default = 100)]
max: u16,
#[prop(into)]
progress: Signal<i32>
) -> impl IntoView {
view! {
<progress max=max value=progress />
}
}
这个东西类似于面向对象中的装饰器,是给函数/属性提供额外能力的一种语法
他有如下几种用法
#[attribute="value"]
#[attribute(key="value")]
#[attribute(value)]
例如,我们将一个普通函数定义为一个组件,则对该函数使用如下的宏定义
#[component]
接收一个参数 max,默认值为 100
#[prop(default = 100)]
max: u16,
支持任意类型的值传入,然后调用 .into() 去转化。
#[prop(into)]
progress: Signal<i32>
因此,有了这个宏的帮助,我们的 progress 属性可以接收一个响应式属性,也可以接收一个普通属性。通过这种方式解决了 solid 在语法设计上面临的困境。
<ProgressBar progress=count />
<ProgressBar progress=|| 100 />
总结
抛开 rust 的上手难度不谈,在语法设计上,Leptos 的语法设计我认为比 solid 要精妙得多。这是一种更成熟的语法构思。
但是响应式方案本身在语法上确实存在挑战,例如在 Solid 中还存在更严重的问题就是使用解构语法会导致数据失去响应性,因此最终也只能靠各种编译手段尽量抹平差异。但黑科技加多了,一不小心就在重新设计语法了。因此到目前为止,我依然更喜欢 React,他的语法设计足够简洁,编译手段的侵入性足够小,更符合 JavaScript 的语法逻辑。