网易首页 > 网易号 > 正文 申请入驻

听说 Signals 快要登陆 React 了?

0
分享至

作者|Paul Scanlon

翻译|核子可乐

编辑|Tina

“Signals”专门用于管理客户端状态,而且从最近的趋势来看,其很有可能在 React 中发挥作用。

就在上周,Dashi Kato(Waku 的缔造者)发布了 use-signals,一个面向 TC39 signals 的实验性 React hook,旨在演示 Signals 如何在 React 中发挥作用。

Signals 是什么?

Signals 已然经历约 10 年的发展周期,先后得到 Angular、Vue、SolidJS、Qwik 以及 Preact 等众多 JavaScript 框架的采纳,用于管理客户端状态。Signals 属于能自动跟踪其使用位置的变量。一旦 Signal 发生变更,其值就会失效,进而触发 UI 状态更新 / 重新渲染。

举例来说,这是一个名为 counter 的 Signal,其值为 0。

const counter = new Signal.State(0);

需要明确的是,Signals 与 React 的 useState 有着本质区别。useState 是 React 提供的 hook,用于管理功能组件内的状态,并允许开发者声明状态变量并更新该变量的函数。

Signals 则是事件的侦听器或者观察器,用于处理异步事件或是超出组件直接控制之外的数据变更。因此,大家会看到 Signal 声明中并没有定义“setter”函数。但配合 React 之后,情况将大为不同。下面来看之前的 Signal 如何在 React 中进行声明:

const [counter, setCounter] = useState(0);

Signals 的概念之所以非常有趣,就是因为 React 那“自上而下”的模型意味着每当有状态值发生变化时,组件树的所有后代都会重新渲染并对 UI 执行相应变更,从而保证 DOM/UI 与应用程序的状态同步。

而在使用 Signals 管理状态之后,开发者能够以更细粒度方式控制对 UI 中的哪些部分进行“重新渲染”。但不要误会,这并不是说 Signals 比 React 方法的性能更高,只是二者的功能定位有所不同。

Signals 使用方法

如上所示,我们可以使用 new 构造函数来声明一个 Signal,例如:

const counter = new Signal.State(0);

之后,要“get”一个 Signal 的值,我们可以使用.get() 方法;而要“set”或者更新一个 Signal,我们可以使用.set() 方法。例如:

counter.get();
counter.set(10);

Signals 在 React 中如何起效?

跟之前提到的 Signals 使用方法不同,它在 React 中另有起效方式。绕过 React 的 diffing 无疑有违 React 声明式编程这一核心原则,因此 React 中的 Signals 仍将使用 VDOM,而且同样会像变更 useState 那样触发重新渲染。

那么在 React 中使用 Signals 还有何意义?其实我的第一反应也是如此,但请大家先别急,让我们一同探索 Signals 的深邃世界。

TC39 提案

如果 TC39 提案获得通过,则意味着 Signals 将在 JavaScript 中原生可用,届时我们将可以在框架之外使用 Signals。更重要的是,框架作者们理论上也能够以标准化方式实现 Signals。换言之,Signals 机制的任何改进都将令所有采用标准化方法的框架受益。而目前,大部分使用 Signals 的框架所采取的处理方式都各有细微差异。

4 月 11 日,Rob Eisenberg 宣布 TC39 提案已经进入第一阶段。这意味着该提案已被纳入 ECMAScript 的考量范围。虽然还有很多工作要做,但这项提案似乎正朝着正确的方向稳步迈进。

TC39 提案还强调了围绕不同框架特定要求的方式开发 API 的重要性。use-signals 的意义也正在于此,它在使用建议 Signals API 的同时,也仍然遵循 React 的核心设计原则。

无论 React 团队最终是否会采纳 Signals,use-signals 的出现都在一定程度上表明 Signals 确实能够在 React 中发挥作用。

Signal Utils 提案

Signals 目前仅支持原语,但也有其他 signal-utils 提案正在推进当中,努力将对象和数组引入其中。例如:

对象

import { SignalObject } from 'signal-utils/object';


let obj = new SignalObject({
isLoading: true,
error: null,
result: null,
});

数组

import { SignalArray } from 'signal-utils/array';


let arr = new SignalArray([1, 2, 3]);

在 React 中使用 Signals 示例

聊了这么多,下面我们一起来看在 React 中具体如何使用 Signals。这里展示的 React 代码在 Waku 上下文中运行,默认在服务器端进行渲染,但其也能支持纯客户端组件的“use client”指令。

与 useState 不同的是,对 Signals 来说,新的 Signals 声明是在组件外部实现的。在以下代码片段当中,也就是名为 counter 的 const,其用于存储初始值并可以被传递至 useSignal hook。

该 count const 公开了.set() 与.get() 方法,这些方法可以在事件处理函数 handleInc 当中使用。

Signal 值的变更将触发 DOM 更新,并在 UI 中显示新的 count 值。

尤其有趣的一点是,在返回的 Jsx 当中,我们不再需要使用.get() 来访问并显示 HTML


元素中的值。相反,现在可以直接访问 count 值。这与 Qwik 的实现略有不同,后者需要我们从 counter 处访问值,例如 counter.value。

'use client';


import { Signal, useSignal } from 'use-signals';


const counter = new Signal.State(0);


const UseSignalComponent = () => {
const count = useSignal(counter);


const handleInc = () => counter.set(counter.get() + 1);


return (
<>
useSignal count: {count} div> Update count button> ); }; export default UseSignalComponent;

useState 组件

为了直观比较,以下代码的业务逻辑不变、只是用 React 的 useState hook 进行编写。可以看到,二者之间几乎没有区别。

'use client';


import { useState } from 'react';


const UseStateComponent = () => {
const [count, setCount] = useState(0);


const handleInc = () => setCount(count + 1);


return (
<>
useState count: {count}


Update count


);
};


export default UseStateComponent;

混合 Signals

总结来讲,在 React 中实现 Signals 完全具备可行性。虽然 Signals 可能需要一段时间才能在 JavaScript 中获得原生身份,但我个人高度赞赏其蓬勃发展的技术社区对于全新开发方式的探索。感兴趣的朋友不妨持续关注 GitHub repo:https://github.com/dai-shi/use-signals。

https://thenewstack.io/did-signals-just-land-in-react/

声明:本文为 InfoQ 翻译整理,未经许可禁止转载。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
韩国孤儿宋宜:8岁被美国女星领养,貌丑心高,27岁嫁给63岁养父

韩国孤儿宋宜:8岁被美国女星领养,貌丑心高,27岁嫁给63岁养父

以茶带书
2026-01-21 17:22:43
曼城崩盘罪人实锤!替补登场拖垮瓜帅,球迷怒喊:滚回意大利!

曼城崩盘罪人实锤!替补登场拖垮瓜帅,球迷怒喊:滚回意大利!

澜归序
2026-02-02 06:26:00
美官员摊牌,郑丽文处境不妙,台名嘴:她得马上去大陆,越快越好

美官员摊牌,郑丽文处境不妙,台名嘴:她得马上去大陆,越快越好

领悟看世界
2026-02-02 17:17:00
不要再随意猜测杨兰兰的身份了,释放的信号很明显了

不要再随意猜测杨兰兰的身份了,释放的信号很明显了

李昕言温度空间
2025-08-20 15:01:53
辽宁整治教师收礼补课:绝不容许躺编寻租坏了教育风气

辽宁整治教师收礼补课:绝不容许躺编寻租坏了教育风气

前沿天地
2026-02-02 14:32:12
闫学晶眼下最发愁的是如何留住儿媳妇,她清楚自儿子配不上梦迪

闫学晶眼下最发愁的是如何留住儿媳妇,她清楚自儿子配不上梦迪

观察鉴娱
2026-01-19 09:28:59
奔驰4款车型迎来官降!至高降幅达6.902万元,网友:早该这么做

奔驰4款车型迎来官降!至高降幅达6.902万元,网友:早该这么做

汽车网评
2026-02-01 22:58:03
纳达尔谈阿卡打破自己纪录:不在意,因为我的职业生涯已经结束

纳达尔谈阿卡打破自己纪录:不在意,因为我的职业生涯已经结束

网球之家
2026-02-02 13:15:12
大量浙江人涌入天津东丽,专找路边60多岁的老头唠嗑,这波操作

大量浙江人涌入天津东丽,专找路边60多岁的老头唠嗑,这波操作

苗苗情感说
2026-02-02 14:56:24
马竞要开启新篇了?小蜘蛛想要思考回归英格兰,功勋主帅也累了

马竞要开启新篇了?小蜘蛛想要思考回归英格兰,功勋主帅也累了

里芃芃体育
2026-02-03 05:00:03
“立春见3鲜,一年病不沾”,2月4号立春,3鲜指啥?要记得吃!

“立春见3鲜,一年病不沾”,2月4号立春,3鲜指啥?要记得吃!

阿莱美食汇
2026-02-03 01:55:08
台湾最新民调出炉,赖清德、郑丽文支持率惊人,萧旭岑亮两张底牌

台湾最新民调出炉,赖清德、郑丽文支持率惊人,萧旭岑亮两张底牌

往事我敬你一杯酒人
2026-02-03 02:44:57
新鹏城总监:在山东的经历让我爱上中国;选陈涛当主帅很明智

新鹏城总监:在山东的经历让我爱上中国;选陈涛当主帅很明智

懂球帝
2026-02-02 15:32:23
服务区变身“巨型货车”!山东高速新添“网红打卡地”

服务区变身“巨型货车”!山东高速新添“网红打卡地”

闪电新闻
2026-02-02 16:41:24
马斯克问爱泼斯坦岛上最狂野派对,明确想参加,曝光后恼羞成怒

马斯克问爱泼斯坦岛上最狂野派对,明确想参加,曝光后恼羞成怒

译言
2026-02-03 06:11:22
春运首日 全社会跨区域人员流动量超1.8亿人次

春运首日 全社会跨区域人员流动量超1.8亿人次

环球网资讯
2026-02-02 19:25:18
沈阳新娘远嫁杭州,娘家30口人自驾送亲,新郎只愿付当天住宿费

沈阳新娘远嫁杭州,娘家30口人自驾送亲,新郎只愿付当天住宿费

兰姐说故事
2025-08-21 20:05:04
朝鲜1月几乎没再给俄罗斯送武器了

朝鲜1月几乎没再给俄罗斯送武器了

桂系007
2026-02-01 05:23:02
从306万跌到50万,我见证了燕郊楼市的“过山车”

从306万跌到50万,我见证了燕郊楼市的“过山车”

靓仔情感
2026-02-02 14:02:19
一个逻辑闭环:阿富汗女性只能上到小学,但女患者又必须看女医生

一个逻辑闭环:阿富汗女性只能上到小学,但女患者又必须看女医生

黄娜老师
2026-02-01 13:45:43
2026-02-03 07:07:00
InfoQ incentive-icons
InfoQ
有内容的技术社区媒体
12016文章数 51732关注度
往期回顾 全部

科技要闻

阿里筑墙,腾讯寄生,字节偷家

头条要闻

周生生足金挂坠戴1天被刮花 检测后发现含铁、银、钯

头条要闻

周生生足金挂坠戴1天被刮花 检测后发现含铁、银、钯

体育要闻

澳网男单决赛,属于阿尔卡拉斯的加冕仪式

娱乐要闻

57岁音乐人袁惟仁去世,家属发文悼念

财经要闻

金银暴跌 全球股市遭遇“黑色星期一”

汽车要闻

雷克萨斯LC500将于今年底停产 "最美雷克萨斯"谢幕

态度原创

亲子
本地
家居
旅游
公开课

亲子要闻

为什么“月子仇”,会让女人记一辈子?

本地新闻

云游中国|拨开云雾,巫山每帧都是航拍大片

家居要闻

现代几何彩拼 智焕童梦居

旅游要闻

解锁勐泐 4 大玩法,读懂真正的傣家风情!

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版