💊

Valtio v1.1.1をリリースしました(React向けのグローバルステートライブラリだけど、Vanillaでも使える)

2021/07/30に公開

https://twitter.com/dai_shi/status/1420737202561052676

とは言っても、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と問題領域は近いけど、アプローチが別な感じです。昔のツイートより:
https://twitter.com/dai_shi/status/1330490462642192384

興味を持った方はお試しあれ。

Discussion