react usecontext_鬼才!我居然把 Vue3 的原理用到了 React 上?

前言

vue-next是Vue3的源码仓库,Vue3采用lerna做package的划分,而响应式能力@vue/reactivity被划分到了单独的一个package中。

如果我们想把它集成到React中,可行吗?来试一试吧。

使用示例

话不多说,先看看怎么用的解解馋吧。

dfeb71d3b461f54826b3ec2c95927755.png
c25fe244d2d1f9ff498921fb17201aa2.png

可以看出,store的定义只用到了@vue/reactivity,而rxv只是在组件中做了一层桥接,连通了Vue3和React,然后我们就可以尽情的使用Vue3的响应式能力啦。

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年我花了一个月整理了一份最适合2020年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。

预览

e77a514fa6330d330d58c7c2f65102c1.png

可以看到,完美的利用了reactive、computed的强大能力。

分析

从这个包提供的几个核心api来分析:

effect(重点)

effect其实是响应式库中一个通用的概念:观察函数,就像Vue2中的Watcher,mobx中的autorun,observer一样,它的作用是收集依赖。

它接受的是一个函数,它会帮你执行这个函数,并且开启依赖收集,

这个函数内部对于响应式数据的访问都可以收集依赖,那么在响应式数据被修改后,就会触发更新。

最简单的用法

c083cc83cc759d0bb0086633c97757d9.png

那么如果把这个简单例子中的

11a09009cb3150da61d675638fa78cd1.png

这个函数,替换成React的组件渲染,是不是就能达成响应式更新组件的目的了?

reactive(重点)

响应式数据的核心api,这个api返回的是一个proxy,对上面所有属性的访问都会被劫持,从而在get的时候收集依赖(也就是正在运行的effect),在set的时候触发更新。

ref

对于简单数据类型比如number,我们不可能像这样去做:

4a8dadbaa891e6e0378ec5173f688cbc.png

这是不符合响应式的拦截规则的,没有办法能拦截到data本身的改变,只能拦截到data身上的属性的改变,所以有了ref。

a72556f4baee8b8ac01a793d3b7295c8.png

computed

计算属性,依赖值更新以后,它的值也会随之自动更新。其实computed内部也是一个effect。

拥有在computed中观察另一个computed数据、effect观察computed改变之类的高级特性。

实现

从这几个核心api来看,只要effect能接入到React系统中,那么其他的api都没什么问题,因为它们只是去收集effect的依赖,去通知effect触发更新。

effect接受的是一个函数,而且effect还支持通过传入schedule参数来自定义依赖更新的时候需要触发什么函数,如果我们把这个schedule替换成对应组件的更新呢?要知道在hook的世界中,实现当前组件强制更新可是很简单的:

useForceUpdate

214ea29511000f3bb69b275545facb0f.png

这是一个很经典的自定义hook,通过不断的把状态+1来强行让组件渲染。

而rxv的核心api: useStore接受的也是一个函数selector,它会让用户自己选择在组件中需要访问的数据。

那么思路就显而易见了:

把selector包装在effect中执行,去收集依赖。

指定依赖发生更新时,需要调用的函数是当前正在使用useStore的这个组件的forceUpdate强制渲染函数。

这样不就实现了数据变化,组件自动更新吗?

简单的看一下核心实现

useStore和Provider

dd5a2da8963a81c209c0db141663cc8b.png

这个option是传递给Vue3的effectapi,

scheduler规定响应式数据更新以后应该做什么操作,这里我们使用forceUpdate去让组件重新渲染。

lazy表示延迟执行,后面我们手动调用effection来执行

8c5ed144670b27bd1d81071f0d44cbda.png

再来看下useEffection和useForceUpdate

0ab8b950130e5faba2553d28f73d3d49.png

也很简单,就是把传入的函数交给effect,并且在组件销毁的时候停止effect而已。

流程

先通过useForceUpdate在当前组件中注册一个强制更新的函数。

通过useContext读取用户从Provider中传入的store。

再通过Vue的effect去帮我们执行selector(store),并且指定scheduler为forceUpdate,这样就完成了依赖收集。

那么在store里的值更新了以后,触发了scheduler也就是forceUpdate,我们的React组件就自动更新啦。

就简单的几行代码,就实现了在React中使用@vue/reactivity中的所有能力。

优点:

直接引入@vue/reacivity,完全使用Vue3的reactivity能力,拥有computed, effect等各种能力,并且对于Set和Map也提供了响应式的能力。后续也会随着这个库的更新变得更加完善的和强大。

vue-next仓库内部完整的测试用例。

完善的TypeScript类型支持。

完全复用@vue/reacivity实现超强的全局状态管理能力。

状态管理中组件级别的精确更新。

Vue3总是要学的嘛,提前学习防止失业!

缺点:

由于需要精确的收集依赖全靠useStore,所以selector函数一定要精确的访问到你关心的数据。甚至如果你需要触发数组内部某个值的更新,那你在useStore中就不能只返回这个数组本身。

举一个例子:

91e9e23b82081a7137a5dabb059385c3.png

这段代码直接在useStore中返回了整段jsx,是因为map的过程中回去访问数组的每一项来收集依赖,只有这样才能达到响应式的目的。

源码地址

https://github.com/sl1673495/react-composition-api

如果你喜欢这个库,欢迎给出你的star✨,你的支持就是我最大的动力~

8c92a5d0045b633d819a303e0fe3286d.png


作者:程序员的青春
链接:https://www.jianshu.com/p/8458d3930f8f

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

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

相关文章

微信多开txt_在电脑上怎么实现微信多开的效果

现在越来越多的年轻人在电脑办公的时候,不止有一个微信号,由于工作、家庭等各方面因素,想自己能在一个电脑上打开多个微信怎么办?下面小编就把自己的所学分享给大家一.首先在电脑桌面上新建一个txt文本文件,把这个文档…

vue slot scope使用_20、slot插槽的用法

重点:单个插槽、具名插槽、作用域插槽的用法;访问插槽的方法。其实本小白对插槽理解的还不深,哪些场景会经常用到插槽也不了解。但是本着“大胆猜测”的理念,我的猜测如下:假设有 父组件A,有 子组件B、子组…

python工作目录_如何使用python 3获取当前工作目录?

When I run the following script in IDLE import os print(os.getcwd()) I get output as D:\testtool but when I run from cmd prompt, I get c:\Python33>python D:\testtool\current_dir.py c:\Python33 How do I get same result which I got using IDLE ? 解决方案 …

flutter刷新页面_用Flutter实现58App的首页

背景Flutter作为全新跨平台应用框架,在页面渲染和MD开发上优势明显,可谓是业界一枝独秀。正好最近有这样的一个机会学习Flutter开发,我们便尝试用它开发一个MD风格的较复杂页面,来比较跟原生应用开发的优势。也是想通过对新框架的…

python调用报表制作工具_使用Python轻松制作漂亮的表格

Python太有用而且很方便 图表可以用matplotlib轻松制作,数值计算只要有numpy就行。 最近,Python被广泛用于机器学习系统的研究,甚至还能制作游戏。 我突然想知道:“是否可以用Python来制作图表而不是表格?” 这个时候&…

小米网关控制空调伴侣_小爱同学怎么控制灯?

说说我们神奇小爱同学吧,小爱同学是小米旗下的一款智能AI音箱,会根据您的指令来操作电器设备,比如说开关灯,那么小爱同学怎么控制灯?如果家里的是传统的灯泡,不是智能灯连接还能控制吗?今天蜜罐…

bochs上网镜像怎么上网_【干货科普】上网慢!经常掉线!怎么办?

文章来源:鲜枣课堂(ID:xzclasscom)作为也算是懂点技术的半专业人士,我们放假回去,遇到亲友,很可能被问到这样的问题——“我的手机(电脑)上网经常掉线,是为什么?”“我的手机(电脑)上网总是很慢…

sql 中位数_【PL/SQL 自定义函数】 常用场景

看完这章后你会学习到以下内容:1.练习场景2.面试场景3.工作应用场景总览思维导图:面试部分:1.创建函数,从emp表中查询指定员工编号的职工的工资CREATE OR REPLACE FUNCTION CHECK_SAL(F_EMPNO IN EMP.EMPNO%TYPE) RETURN NUMBER ISV_SAL VARC…

swift date 计算差_[Swift 设计模式] 适配器

更多内容,欢迎关注公众号:Swift花园喜欢文章?不如来个 ➕三连?关注专栏,关注我 将一个不兼容的对象转换成目标接口或者类,这是适配器模式的作用。下面这件东西是适配器模式在现实世界中最贴切的表达。 USB-…

委外订单_听听晚报-英特尔扩大芯片委外订单、苹果秋季或举行两场发布会

英特尔扩大芯片委外订单据外媒报道称,美国半导体厂商英特尔已与中国台湾芯片制造厂商台积电达成协议,明年开始采用后者7nm的优化版本6nm制程量产处理器或显卡,预估投片量将达到18万片。该消息发出后,资本市场反应剧烈,…

打开另外一个页面_如何在PDF页面中插入图片?

如何给PDF添加图片?有些时候为了丰富PDF的文档内容,需要添加一些图片,相比Word或PPT文档可以直接插入图片,而PDF的操作很多人可能并不熟悉,下面一起来看看如何在PDF文档中插入图片。关于PDF文档插入图片分为两种情况&a…

spring boot mybatis 整合_MyBatis学习:MyBatis和Spring整合

1. 整合的工程结构首先我们来看下整合之后的工程结构是什么样的。2. 配置文件在于spring整合之前,mybatis都是自己管理数据源的,然后sqlSessionFactory是我们自己去注入的,现在整合了,这些都要交给spring来管理了,来看…

python中缩进_python编程中的缩进是什么意思

Python最具特色的是用缩进来标明成块的代码。我下面以if选择结构来举例。if后面跟随条件,如果条件成立,则执行归属于if的一个代码块。 下面对比C语言来看一下if ( i > 0 ) { x 1; y 2; } 如果i > 0的话,我们将进行括号中所包括的两个…

返回后的数据处理_【掘金使用技巧2】掘金返回数据中时间的处理方法

掘金输出的时间数据处理方法掘金在为使用者提供数据时,有一类数据处理起来有些麻烦,这类数据就是时间数据。它们长这样:或者这样:查看一下它们的类型,发现有datetime,datetime64,Timestamp等等。这么多各种各样的类型&…

springboot jwt token前后端分离_为什么要 前后端分离 ?

作 者:互扯程序来 源:互扯程序广而告之:由于此订阅号换了个皮肤,系统自动取消了读者的公众号置顶。导致用户接受文章不及时。您可以打开订阅号,选择置顶(星标)公众号,重磅干货,第一时间送达&…

分计算iv值_一文读懂评分卡的IV、KS、AUC、GINI指标

前言:当一张评分卡构建完成时,筛选出一组特征生成了分数,我们会想要知道这个分数是否靠谱,即是否可以依赖这个分数将好坏客户区分开来,这个时候就需要评判评分卡有效性的指标。测量评分卡好坏区分能力的指标有许多&…

linux 查找文件夹_用python打造一个基于socket的文件(夹)传输系统

这段时间在学习python,接触到了网络编程中的socket这块,加上自己在用的Linux服务器都是原生支持python的,于是乎有了个做文件传输功能程序的想法。毕竟python语言中,有下载功能的框架一抓一大把,但是主机与主机间快速搭…

mysql gtid 备份恢复_MySQL基于gtid特性与xtrabackup的数据恢复

一、gtid特性介绍:GTID(global transaction identifier)是MySQL 5.6的新特性,可以唯一的标识一个事务,由UUIDTID组成:UUID是MySQL实例的唯一标识TID是该实例上已提交的事务的数量在主从复制中,GTID代替了classic的复制…

编码gbk的不可映射字符_Python基础:编码表和字符的故事

在计算机内部,都是每8位组成的一个个字节,比如我们使用"abc".encode()把abc转化成二进制byte类型,注意byte是不可变类型: 编码过程>>> abc.encode() # 把str字符变为bytes字节类型;字符是一个个连接…

mysql 中文字段名_MySQL全文索引怎么做?| 教程分享

- 点击上方“爱数据学习社”关注我们吧! -文末领取【商业分析资料】为什么要用全文索引我们在用一个东西前,得知道为什么要用它,使用全文索引无非有以下原因:like查询太慢、json字段查询太慢(车太慢了)没时间引入ElasticSearch、S…