我厭倦了 Redux,那就造個輪子 Rectx:第三集

215566435發表於2019-02-16

倉庫:215566435/rectx

前言

麻煩快去我的倉庫裡面噴:

老子學不動了,求不要更新。

呵呵,你沒想到吧,這玩意兒竟然有第三集!我靠,我自己都沒想到,讓我們悄悄的回顧一下前兩集
完全沒想到,竟然會有第二集!

我厭倦了 Redux,那就造個輪子 Rectx 第二集: immutable 痛點分析

第一集在這裡:我厭倦了Redux,那就造個輪子:Rectx

算了,我都懶得寫了,自己看吧,當然不看也無所謂,正式開始。

新的 Rectx 有什麼不同?

a light-weight state manager with mutable api.

有人就說了,你說 light-weight來喂??那是肯定是,這個庫大小隻有幾 k 。其次,新版的 Rectx 並不依賴 React.context,因此可以在任何 react 版本中使用。

當然,短短60行核心程式碼,我寫了不少的測試,覆蓋率也來到了98%。

那,為什麼又更新了?

ReduxMobx都非常的棒,但對於大部分專案都只是CRUD的專案來說,這些個玩意兒都略顯太重了。

而且對於reactimmutable 哲學而言,實在是模版程式碼相當的多,對新手、高手、熟練工都不是很友好:新手覺得複雜,高手覺得煩躁,熟練工覺得不夠快。

再加上,react函數語言程式設計以及 DOM-diff 依賴的是html tag的緣故,因此我們需要手動優化 React 的效能,臭名昭著的shouldComponentUpdate由此而來。

為了更好的解決上述的一些問題,我開始尋找一種方式能夠解決:
模版化很少

  • 無需手動 shouldComponentUpdate
  • API 極少,學習成本低
  • mutable API
  • 以下就是我的解決方案。

特點

rectx 有著強大的功能,他不僅能提供一個狀態庫,甚至能提供一個良好的型別輔助系統,這也意味著你可以在 TypeScript中支援它!

  • 並不依賴 react.context api,支援 15、16 版本的 react
  • mutable api,再也不用寫模版程式碼
  • 完整的測試,測試覆蓋率極高
  • typescriptd.ts 支援,非常友好的型別提示
  • 不用寫 shouldComponentUpdate 的元件 Auto(自動)
  • 高效能,輕量

最簡單的使用
當然了,這個例子如果你看就懂,那我非常建議你直接去看我是如何處理,使得不需要寫shouldComponentUpdatecode 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

code sandbox例子

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 了。

型別提示
得益於 typescriptRectx得到了良好的型別提示。

render props 中會有提示
當我們初始化store以後,我們的store裡面具體有什麼值,在純 js 中並沒有智慧提示,但加入了 ts 之後,一切會大不一樣

更新的時候也能有提示

最後,請不要吝嗇你的星星,倉庫:倉庫:215566435/rectx

相關文章