💊
Valtio v1.1.1をリリースしました(React向けのグローバルステートライブラリだけど、Vanillaでも使える)
とは言っても、valtioを知らない人がほとんどでしょうから、何か紹介できないかなと。
valtioはreactのglobal state用のライブラリですが、reactではなくvanilla javascriptでも使えます。immerのようなものです。今回はその方向で紹介してみようと思います。
と言っても疑似コードを載せるだけ
import { proxy, snapshot, subscribe } from 'valtio/vanilla';
// 最初に初期オブジェクトを指定してproxyを作る
const p = proxy({ a: 1 });
// pはただのオブジェクトなので普通にいじれる
++p.a;
// 内部的には変更を追跡していて、immutableなsnapshotがとれる
const snap1 = snapshot(p);
console.log(snap1); // { a: 2 }
// snapshotはキャッシュされている(最後の一つだけ)
const snap2 = snapshot(p);
console.log(snap1 === snap2); // true 同じものが返ってくる
// さらにいじる
p.b = 1;
// 当然snapshotが変わる
const snap3 = snapshot(p);
console.log(snap3); // { a: 2, b: 1 }
// オブジェクトをネストすることもできる
p.obj = { c: 0 };
// 基本的に期待通りに動く
const snap4 = snapshot(p);
console.log(snap4); // { a: 2, b: 1, obj: { c: 0 } }
// 一部をいじる
p.a = 3;
// snapshotはどうなるかというと
const snap5 = snapshot(p); // これは { a: 3, b: 1, obj: { c: 0 } }
console.log(snap4 !== snap5); // true 当然別のスナップショットなので
console.log(snap4.obj === snap5.obj); // true objは変わってないので共通・最適化
// コールバックを登録できる
subscribe(p, () => { console.log('changed'); });
// 変更すると
p.b++; // "changed"がコンソールに表示される
// ネストされたオブジェクトを変更しても
p.obj.c++; // ちゃんと"changed"が表示される
// そういえば、配列も使える
p.arr = []; // "changed"
p.arr.push('a'); // "changed"
const snap6 = snapshot(p); // { a: 3, b: 2, obj: { c: 1 }, arr: ['a'] }
// 基本何でもできる
p.arr.unshift({});
p.arr[0].text = 'hello';
const arr = p.arr; // 別の変数に入れても大丈夫
arr.push('b');
arr.pop();
delete p.a;
// 循環参照もできちゃう(何に使うんだろ)
p.me = p;
これで大体説明できたでしょうか。伝わるか不明ですが。どうでしょうイメージできましたか?
immerと問題領域は近いけど、アプローチが別な感じです。昔のツイートより:
興味を持った方はお試しあれ。
Discussion