我厌倦了 Redux,那就造个轮子 Rectx:第三集
前言
麻烦快去我的仓库里面喷:
老子学不动了,求不要更新。
呵呵,你没想到吧,这玩意儿竟然有第三集!我靠,我自己都没想到,让我们悄悄的回顾一下前两集
完全没想到,竟然会有第二集!
我厌倦了 Redux,那就造个轮子 Rectx 第二集: immutable 痛点分析
算了,我都懒得写了,自己看吧,当然不看也无所谓,正式开始。
新的 Rectx 有什么不同?
a light-weight state manager with mutable api.
有人就说了,你说 light-weight
就 来喂
??那是肯定是,这个库大小只有几 k 。其次,新版的 Rectx
并不依赖 React.context
,因此可以在任何 react
版本中使用。
当然,短短60行核心代码,我写了不少的测试,覆盖率也来到了98%。
那,为什么又更新了?
Redux
和Mobx
都非常的棒,但对于大部分项目都只是CRUD
的项目来说,这些个玩意儿都略显太重了。
而且对于react
的 immutable
哲学而言,实在是模版代码相当的多,对新手、高手、熟练工都不是很友好:新手觉得复杂,高手觉得烦躁,熟练工觉得不够快。
再加上,react
函数式编程以及 DOM-diff
依赖的是html tag
的缘故,因此我们需要手动优化 react
的性能,臭名昭著的shouldComponentUpdate
由此而来。
为了更好的解决上述的一些问题,我开始寻找一种方式能够解决:
模版化很少
- 无需手动
shouldComponentUpdate
- API 极少,学习成本低
mutable API
- 以下就是我的解决方案。
特点
Rectx
有着强大的功能,他不仅能提供一个状态库,甚至能提供一个良好的类型辅助系统,这也意味着你可以在 TypeScript
中支持它!
- 并不依赖
React.context
api,支持 15、16 版本的 react mutable API
,再也不用写模版代码- 完整的测试,测试覆盖率极高
TypeScript
的d.ts
支持,非常友好的类型提示- 不用写
shouldComponentUpdate
的组件Auto
(自动) - 高性能,轻量
最简单的使用
当然了,这个例子如果你看就懂,那我非常建议你直接去看我是如何处理,使得不需要写shouldComponentUpdate
的code sandbox 例子:
import React from 'react'; import {render} from 'react-dom'; import {init} from 'rectx'; const {Put, Ctx} = init({foo: 1}); const App = () => ( <div> <Ctx>{s => <div>{s.foo}</div>}</Ctx> <button onClick={() => Put(s => (s.foo = s.foo + 1))}>add</button> </div> ); render(<App />, document.getElementById('root'));
使用 <Ctx/>
的 renderProps
的形式,就能拿出我们想要的数据.
值得注意的是,Put(s => (s.foo = s.foo + 1))
在这里,我们直接修改了我们的数值,当数据非常复杂的时候,这种操作方式尤为珍贵。
无需 shouldComponentUpdate
的组件 Auto
import { init } from "rectx"; const { Put, Ctx, Auto } = init({ foo: 1, bar: 1 });
首先我们依然是引入我们的组件,Put
用于更新,Ctx
用于获取,那么 Auto
是一个什么鬼?
Auto
是一个选择器,他能够分离我们的 Store
,把每一个 Store
切分成一个小粒度的块,使得我们的代码更加简洁。比如我们想获取全局状态 Store
中的,bar
,我们就可以:
const Bars = Auto(s => s.bar);
当我们使用Bars
的时候,我们获取到的就是 bar
这个属性了。当然,Auto
翻译为自动,这是他第一个自动的地方,第二个特点请看下面:
import React from "react"; import { render } from "react-dom"; import { init } from "rectx"; const { Put, Ctx, Auto } = init({ foo: 1, bar: 1 }); const Bars = Auto(s => s.bar); const App = () => ( <div> <Ctx>{s => <div>Foo:{s.foo}</div>}</Ctx> {Bars(bar => <div>Bar:{bar}</div>)} <button onClick={() => Put(s => (s.foo = s.foo + 1))}>change Foo</button> <button onClick={() => Put(s => (s.bar = s.bar + 1))}>change Bar</button> </div> ); render(<App />, document.getElementById("root"));
首先 Auto
是一个 selector
,其作用是获取全局的状态,从中选出 你关心的 属性,当这些属性被选择出来以后,只要这些属性没有被更新,那么他们所返回的组件 一定不会 更新。同时,外部的属性是否更新,跟他们同样没有任何关系。
熟悉 react
的同学,一定知道这么做的珍贵之处,再也不用手动书写 shouldComponentUpdate
了。
类型提示
得益于 TypeScript
,Rectx
得到了良好的类型提示。
render props
中会有提示
当我们初始化Store
以后,我们的Store
里面具体有什么值,在纯 js
中并没有智能提示,但加入了 ts
之后,一切会大不一样
更新的时候也能有提示
最后,请不要吝啬你的星星,仓库:仓库:215566435/rectx