はじめに
この記事は React のステート管理向けのライブラリを書いて使ってみているけれど、
かなり便利なものになったので、それを書くに至った経緯とか実装中に調べていたライブラリ周りの紹介をします。
作ったもの
hrsh7th/srimmer
https://github.com/hrsh7th/srimmer
かなり軽量なステート管理向けのライブラリで、まだ実装途中だけど自分で使ってみている。ちなみに、あとで紹介する予定だけど react-copy-write っていうのに相当インスパイアされている。TypeScript で確実に型が推論されることと、あまり意識せずともパフォーマンスが悪化しないように意識して作っている。簡単な使い方は以下。
import React from 'react';
import ReactDOM from 'react-dom';
import { define } from 'srimmer';
type State = {
count: number;
};
const {
Provider,
select,
update
} = define<State>();
const Consumer = select(state => ({
count: state.count
}));
ReactDOM.render(
<Provider state={initialState()}>
<Consumer>
{state => (
<div>{state.count}</div>
)}
</Consumer>
</Provider>,
document.getElementById('app')!
);
setInterval(() => {
update(state => {
state.count++;
});
}, 1000);
経緯
immer というライブラリが公開されているのを知り、「これは便利!」と思っていたのだけれど、触ってみることはできていなかった。
そんなこんなで時間が経ってから「ガントチャートを表示するツールを作るぞー!」という機運が自分の中で高まり、実装を開始した。
その時に選定したスタックが TypeScript + React + immer + react-copy-write だった。
しかし、react-copy-write が TypeScript と相性が悪くて、コード量もそんなでもないし自作しよう!と思い至った。
どうなの?
書き味は今の所最高。
パフォーマンスのチューニングもしやすい。
実際のコードはまだまだ実装途中だけど、ganttcharty ここにおいてあるので興味があれば見てもらうといいかもしれない。(
紹介とか
immer
mutable な操作を ES.Proxy で trap して immutable な操作に翻訳してくれる。
また、操作自体を内部的に全て trap しているので Redux の time traveling のようなことが JSON-Patch で実現できるようになっている。
import produce from 'immer';
const state = {
value: 1
};
const newState = produce(state, state => {
state.value++;
});
state.value //=> 1
newState.value //=> 2
react-copy-write
上記の immer を利用して、React につなぎ込みを行うライブラリ。
終わりに
食わず嫌いはやめて Redux 触らないとだめなのかなあとは思ってはいる。
(が、どうしても Redux が正解とは未だに思えてない。。。)
この記事を読んで immer と react-copy-write を覚えて帰っていただければ満足です!