谈谈我对 Reacitive 方法的理解

本文我想和大家分享一下我对当前 Reactivity 方法和现状的理解。我并不是说我的观点就是对的,但我认为,正是通过分享自己的观点,我们才能对行业中的事物达成共识,我希望这些来之不易的见解能够对其他人有所帮助,并补充他们理解中缺失的部分。

reacitve 三剑客

我认为到目前为止,我们在行业中看到的 reacitive 方法有三种:

  1. 基于 value:也就是脏检查,应用的框架有 Angular, React, Svelte;
  2. 基于 observable : 应用的框架有 Angular with RxJS, Svelte;
  3. 基于 singnal:应用的框架有 Angular with signals, Qwik, React with MobX, Solid, Vue

接下来我来谈谈这三种方法:

基于 value

基于 value 的系统依赖于将状态作为简单值存储在“不可观察”引用中。

当我 说“observable” 时,我并不是指的是像 RxJS 这样的可观察对象。我指的是“可观察”这个词的常用用法,比如知道它什么时候发生了变化。“不可观察”意味着当值发生变化时,没有办法及时知道具体的实例。下面我给出三个例子:

  • React
function Counter() {const [count, setCount] = useState(0)return <button onClick={() => setCount(count + 1)}>{count}</button>
}
  • Angular
import { Component } from '@angular/core';@Component({selector: 'app-counter',template: `<h1>Counter: {{ count }}</h1><button (click)="increment()">Increment</button>`,
})
export class CounterComponent {count: number = 0;increment() {this.count++;}
}
  • Svelte
<script>let count = 0;function increment() {count += 1;}
</script><div><h1>Counter: {count}</h1><button on:click={increment}>Increment</button>
</div>

在上面的每种情况下,状态都作为一个值存储在变量中。但关键是它是一个不可观察的值,以一种不允许框架知道(观察)值何时变化的方式存储在 JavaScript 中。

由于该值的存储方式不允许框架观察到变化,因此每个框架都需要一种方法来检测这些值何时发生变化,并将组件标记为脏组件。

一旦标记为 dirty,就会重新运行组件,以便框架可以重新读取/重新创建值,从而检测哪些部分发生了更改,并将更改反映到 DOM。

脏检查是基于 value 的系统所能采用的唯一策略。它将最后一个已知值与当前值进行比较

那怎么知道什么时候运行脏检查算法呢?通常不同的框架方式不同:

  • Angular: 隐式依赖 zone.js 来检测状态何时可能发生了变化。(因为它依赖于通过zone.js 的隐式检测,所以运行变更检测的频率比严格必要的要高。)
  • React: 显式依赖于开发人员调用 setState()
  • Svelte: 自动生成 setState() 调用

基于 Observable

Observable 对象是随时间变化的值。Observable 对象允许框架在值发生变化时及时知道具体的实例,因为将新值推送到 Observable 对象中需要特定的 API 来充当保护。

可观察对象是解决细颗粒 Reacitive 问题的明显方法。但是,因为 observable 需要显式调用 .subscribe() 和相应的调用 .unsubscribe(),导致开发体验不好 。可观察对象也不能保证同步无故障的交付,UI 倾向于同步更新。下面我们给出代码示例:

  • Angular
import { Component } from '@angular/core';
import { Observable, BehaviorSubject } from 'rxjs';@Component({selector: 'app-counter',template: `<h1>Counter: {{ count$ | async }}</h1><button (click)="increment()">Increment</button>`,
})
export class CounterComponent {private countSubject = new BehaviorSubject<number>(0);count$: Observable<number> = this.countSubject.asObservable();increment() {this.countSubject.next(this.countSubject.value + 1);}
}
  • Svelte
<script>import { writable } from 'svelte/store';const count = writable(0);function increment() {// Update the count by incrementing itcount.update(n => n + 1);}
</script><div><h1>Counter: {$count}</h1><button on:click={increment}>Increment</button>
</div>

Svelte: 有趣的是,它有两个具有不同心智模型和语法的 Reacitive 系统。这是因为基于value 的模型只在 .svelte 文件中工作,所以将代码移出 .svelte 文件需要一些其他的 Reacitive 原语(Stores)。

我相信每个框架都应该有一个可以处理所有用例的单一 Reacitive 模型,而不是基于用例的不同 Reacitive 系统的组合。

基于 Signal

Signal 就像可观察对象的同步表兄弟没有订阅/取消订阅。我相信这是一个重大的编码改进,我也相信 Signal 是未来。

Signal 的实现并不明显,这就是为什么行业花了这么长时间才走到这一步。Signal 需要与底层框架紧密耦合,以获得最佳的编码体验和性能。

为了获得最好的结果,需要协调框架渲染和可观察对象更新。下面给出几个示例:

  • Qwik
export const Counter = component$(() => {const count = useSignal(123);return (<button onClick$={() => count.value++}>{count.value}</button>);
});
  • SolidJS
export const Counter = (() => {const [count, setCount] = createSignal(123);return (<button onClick={() => setCount(count() + 1)}>{count()}</button>);
});
  • Vue
<template><section><h1>Count: {{ count }}</h1><button @click="incrementCount">+1</button></section>
</template><script setup>
import { ref } from 'vue';const count = ref(0);
function incrementCount() {count.value++;
}
</script>

Angular 正在研究 Signal ,但它们仍然需要 Signal 和模板的集成。

最后,总结一下我的观点。

可观察对象太复杂了,不太适合。因为只有 BehaviorSubject 可观察对象才能真正与 UI 一起工作。

在基于 Value 的系统中,性能又是极其消耗的。虽然值的变化不会破坏应用程序,只是当有一天你觉它太慢了的时候,并且当你想要进行优化它时,就会发现没有“明显”的东西需要修复。

对于基于 Signal 的系统,对于开发者,最初的理解门槛会稍微高一些,并且开发者很有可能从 Reacitive 悬崖上掉下来。因为如果你对 Signal 的反应错误,应用程序就会崩溃。但是解决问题的办法也会很明显。

其次,当一旦你开始优化基于 Value 的系统的时候,你就会开始接触到基于 Signal 的世界,在那里你可能会像处理 Signal 一样失去 Reacitive。本质上,基于 Value 的“优化”API是“低于标准的 Signal 的”。

这也是我喜欢 Signal 的第二个原因。Signal 开启了一种很酷的编码方式,它允许你可视化系统的响应式并调试它。

好啦,以上就是我的理解,希望对你有帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/123757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++初探:简单易懂的入门指南】二

【C初探&#xff1a;简单易懂的入门指南】二 1.引用1.1引用做函数的参数1.2 引用做返回值1.2.1 关于引用做返回值的几点补充 1.3 多引用(对一个变量取多个别名)1.4 引用类型一致性原则以及权限的问题阐述1.5引用的效率问题1.6引用和指针的比较 2.auto关键字2.1 auto关键字的使用…

react中的forwardRef 和memo的区别?

文章目录 前言介绍forwardRefmemo适用场景优点缺点后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端面试 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错…

VUE重学

v-if和v-show的区别&#xff1a; v-if是按条件渲染&#xff0c;因为他确保在切换时&#xff0c;条件区块内的事件监听器和子组件都会被销毁和重建&#xff0c;也是惰性的&#xff0c;如果初次渲染条件为false&#xff0c;则不会做任何事&#xff0c;只有true才会渲染 v-show:无…

springMVC 面试题

一、springMVC 面试题 1.Spring MVC的常用注解由有哪些&#xff1f; Controller&#xff1a; 用于标识此类的实例的是一个控制器 RequestMapping: 映射url路劲 ReponseBody: 返回JSON数据 RequestBody&#xff1a;将JSON数据转换为json数据&#xff0c;将json数据转换为Ja…

共谈信创谋发展 | 开源网安主办的信创生态构建沙龙圆满完成

​10月26日&#xff0c;由珠海市工业和信息化局、珠海市高新区科技创新和产业发展局指导&#xff0c;珠海华发产业园与开源网安珠海公司等联合主办的“赋能数字转型 提速国产替代”—Uni-Idea信创生态构建沙龙在华发信创产业园成功举办&#xff0c;近百位行业代表参加本次活动&…

使用requests库进行HTTP爬虫编程

目录 一、安装requests库 二、发送HTTP请求 三、解析HTML页面 四、处理HTTP响应和异常 五、使用代理和会话管理 六、使用多线程或多进程提高效率 七、数据存储和处理 八、注意事项和总结 在当今的数字化世界中&#xff0c;数据已经成为了一种宝贵的资源。而网络爬虫程序…

使用SweetAlert2 弹层(模态,提示框,过几秒消失......等等)

最近在做一个Asp.net MVC的项目&#xff0c;里面用部分视图页弹层&#xff0c;感觉很不爽&#xff0c;用着别扭。在前后端分离的项目里&#xff0c;我们肯定用封装好的前端UI库了&#xff0c;比如element ui&#xff0c;但是 Asp.net MVC的项目里面集成这个比较困难...... 就找…

基本微信小程序的体检预约小程序

项目介绍 我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;体检预约系统小程序被用户普遍使用&#xff0c;为方便用户…

使用ControlNet生成视频(Pose2Pose)

目录 ControlNet 介绍 ControlNet 14种模型分别是用来做什么的 ControlNet 运行环境搭建 用到的相关模型地址 ControlNet 介绍 ControlNet 是一种用于控制扩散模型的神经网络结构&#xff0c;可以通过添加额外的条件来实现对图像生成的控制。它通过将神经网络块的权重复制到…

OPNET <<< Program Abort >>> Standard function stack imbalance

OPNET <<< Program Abort >>> Standard function stack imbalance OPNET 问题原因及解决办法 OPNET 问题 OPNET仿真时遇到此问题&#xff1a; <<< Program Abort >>> Standard function stack imbalance 原因及解决办法 出现此问题是因…

【开题报告】基于Springboot的母婴商城设计与实现

1.研究背景与目的 随着社会发展和人们生活水平的提高&#xff0c;母婴市场逐渐兴起并蓬勃发展。为了满足消费者对母婴产品的需求&#xff0c;建立一个高效、可靠的母婴商城系统变得尤为重要。本项目旨在通过使用Spring Boot框架&#xff0c;设计和实现一个功能完善、易于扩展的…

Maven compile时报错 系统资源不足,出现OOM:GC overhead limit exceeded

今天在对项目进行Maven clean compile的时候&#xff0c;报出了如下的错误&#xff0c; 系统资源不足。 有关详细信息&#xff0c;请参阅一下堆栈跟踪。 java.lang.OutOfMemoryError: GC overhead limit exceededat java.util.EnumSet.noneOf(EnumSet.java:115)at com.sun.too…

半导体设备:静电卡盘

静电卡盘是半导体设备的核心组件之一&#xff0c;对于控制晶圆的温度&#xff08;加热及冷却&#xff09;至关重要。静电卡盘&#xff08;简称 ESC 或者 E-CHUCK&#xff09;具有高稳定性、晶圆平坦度高、颗粒污染小、边缘效应小等优势&#xff0c;目前已广泛应用在等离子和真空…

2.10、自定义量化优化过程

introduction 如何自定义量化优化过程,以及如何手动调用优化过程 code from typing import Callable, Iterableimport torch import torchvision from ppq import QuantizationSettingFactory, TargetPlatform from ppq.api import (ENABLE_CUDA_KERNEL, QuantizationSetti…

QT如何检测当前系统是是Windows还是Uninx或Mac?以及是哪个版本?

简介 通过Qt获取当前系统及版本号&#xff0c;需要用到QSysInfo。 QSysInfo类提供有关系统的信息。 WordSize指定了应用程序编译所在的平台的指针大小。 ByteOrder指定了平台是大端序还是小端序。 某些常量仅在特定的平台上定义。您可以使用预处理器符号Q_OS_WIN和Q_OS_MACOS来…

【设计模式】第14节:结构型模式之“代理模式”

一、简介 代理模式&#xff08;Proxy Design Pattern&#xff09;在不改变原始类&#xff08;或叫被代理类&#xff09;代码的情况下&#xff0c;通过引入代理类来给原始类附加功能。 二、优点 关注点分离访问控制延迟实例化远程访问缓存增加附加功能 三、应用场景 访问控…

【2021集创赛】海云捷迅杯一等奖:基于稀疏卷积与层融合的流水线优化方案

海云捷迅杯:基于FPGA C5Soc的MobileNetV1 SSD目标检测方案设计 本作品参与极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动。 **杯赛题目&#xff1a;**海云捷迅杯——基于FPGA C5Soc的MobileNetV1 SSD目标检测方案设计 设计任务&#xff1a; 基于已训…

【MedusaSTears】正则表达式搜索心得

文章目录 心得体会1.懒惰匹配最少字符 .?2.前瞻: 字符串后边 包括/不包括 某个单词/字母2-1.包含某单词: start(?.?hello)2-2.不包含某单词: start(?!.?hello) 心得体会 前情回顾: 【MedusaSTears】正则?不要太简单!—正则表达式个人学习心得总结: 正则说白了是对字符串…

关于pycharm中句号变成点的问题

现象 在pycharm的使用中&#xff0c;经常遇到一个问题&#xff1a;注释写着写着&#xff0c;突然句号“。”变成了“.” 原因 今天突然发现&#xff0c;造成该现象的原因是&#xff1a;某个瞬间按下了ctrl .&#xff0c;那么之后按下句号只能显示为点。 pycharm中&#xf…

STM32G030F6P6 芯片实验 (一)

STM32G030F6P6 芯片实验 (一) 淘宝搞了几片, 没试过 G系列, 试试感觉. 先搞片小系统版: 套 STM32F103C8T6小系统板格式. 原理图: (1) Ref 有点跳, 从 STM32F103C8T6 系统板改的, 没重编号. (2) Type-C 纯给电, 砍了 16pin的, 直接换 6pin的。 (3) 测试LED放 B2。 (4) 测试底…