generated at
Immutable.js
不変の永続データ構造を扱う
遅延評価をサポート


dev toolsを開けば実行できるようになっている
playcodeの左側でimmutable.js入れれば使える

ざっくりAPI
List, Stack, Map, OrderdMap, Set, OrderedSet. など
Record でクラスと同じような使い方ができる(?)
Seq 遅延評価のための型
fromJS() , toJS() で普通のjsとの変換ができる
コストはかかる


まずは何から触ればいい?
List: 配列っぽいやつ
JavaScript
// 使わない const list1 = [1, 2, 3]; const list2 = list1; list2.push(4); list1 // [1, 2, 3, 4] ← 変わってる list2 // [1, 2, 3, 4] // 使う const { List } = require('immutable@4.0.0-rc.9'); const list1 = List([ 1, 2, 3 ]); const list2 = list1.push(4); list1; // [1, 2, 3] list2; // [1, 2, 3, 4]
Map: Objectっぽいやつ
JavaScript
// immutable.jsを使わないパターン const dmap1 = {a: 1, b: 2, c: 3}; const dmap2 = dmap1; dmap2['a'] = 100; dmap1['a']; // 100 ← 変わってる dmap2['a']; // 100 // immutable.jsを使うパターン const { Map } = require("immutable"); const map1 = Map({ a: 1, b: 2, c: 3 }); const map2 = map1.set('a', 100); map1.get('a'); // 1 map2.get('a'); // 100 // TypeScriptでimmutable.jsを使う import Immutable from require('immutable'); const map1: Immutable.Map<string, number> = Immutable.Map({ a: 1, b: 2, c: 3 }); const map2 = map1.set('a', 100); map1.get('a'); // 1 map2.get('a'); // 100
Record: Interfaceみたいなやつ
中にはプロパティやメソッドを書く
Interfaceとは違い、型ではなく初期値を入れる
継承してクラスを作る
JavaScript
const PersonRecord = Immutable.Record({ // 初期値 name: 'tarou', age: 20 }); class Person extends PersonRecord { public getName() { return this.name; } public getAge() { return this.age; } } const person = new Person(); const name = person.getName(); const age = person.getAge(); console.log(name); console.log(age);


メリット
パフォーマンス改善
なんで?

デメリット
一度入れたら途中でやめられない


updateって一つの項目ずつ更新するん?
js
hoge = { piyo: { circles: ['茶道', 'ぷろぐらみんぐ'], age: 23 } }
みたいなデータのcirclesもageも更新したいときって
js
hoge.updateIn(['piyo', 'circles'], c => {circleの更新処理}) .updateIn(['piyo', 'age'], a => a-1)
それとも以下のようにやるのか
できるのか?
js
hoge.update('piyo', piyo => { 両方の更新処理 } )


hoge() hogeIn() の違い
hoge()
hogeIn(['prop1', 'prop2',..], l => update(l))
入れ子になっているデータ構造にアクセスするときは hogeIn() を使う(?)
第一引数でそのオブジェクトのプロパティを指定して、そこに対して第二引数の関数を適用する
配列の中でプロパティを指定するのがちょっと異質だが、要するに
通常のJSで hoge.piyo.foo とアクセスしているのを、
['hoge','piyo','foo'] としてアクセスしている
js
hogepiyo.getIn(['hoge', 'piyo', 'foo']); // => 6 const hogepiyo2 = hogepiyo.updateIn(['hoge', 'piyo', 'foo'], v => v + 1); // => Map { hoge: Map { piyo: Map { foo: 7 } } }

Immutable.jsでRecordから一致するものを検索する
keyが一致
簡単
ts
const newPost = postModel.updateIn( ['posts', postId, 'comments'], // `postId`をkeyで探している () => comments );
値が一致
findIndex を使う
なぜかドキュメントにない
ts
const targetIndex = comments.findIndex(c => c.commentId === commentId); const comments = comments.remove(targetIndex);
参考

Immutable.jsで値が一致したものを削除、などの操作をしたいとき


withMutationsとは
ふつうにやったら
js
let b = a.set(...) b = b.update(...) b = b.update(...)
とか
js
let b = a.set(...).update(...).update(...)
とかなるが、
とかやって毎回毎回値を返して更新するが
js
let b = withMutations(a => a.set(...).update(...).update(...)
とやるとパフォーマンス的に良いらしい



toJS() するとそのプロパティの型が全部anyになるのをちゃんとしたい

fromJS
toJSの逆の概念

React + Immutable.js