最近在用 React-Dnd 做拖拽效果的時候欠痴,順帶學習到了 immutability-helper
這個庫陋气。我覺得它主要是讓我們能夠更加優(yōu)雅的去操作并創(chuàng)建一個新對象。
用法
在不用到 immutability-helper
的情況下我們通常是這么操作對象和數組的:
myData.x.y.z = 7;
// or...
myData.a.b.push(9);
const newData = deepCopy(myData);
newData.x.y.z = 7;
newData.a.b.push(9);
const newData = Object.assign({}, myData, {
x: Object.assign({}, myData.x, {
y: Object.assign({}, myData.x.y, {z: 7}),
}),
a: Object.assign({}, myData.a, {b: myData.a.b.concat(9)})
});
在使用了 immutability-helper
后,操作對象變得優(yōu)雅了起來淹冰。
import update from 'immutability-helper';
const newData = update(myData, {
x: {y: {z: {$set: 7}}},
a: {b: {$push: [9]}}
});
const initialArray = [1, 2, 3];
const newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
// => [1, 2, {a: [12, 13, 14, 15]}]
const obj = {a: 5, b: 3};
const newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
// => {a: 5, b: 6}
// This is equivalent, but gets verbose for deeply nested collections:
const newObj2 = update(obj, {b: {$set: obj.b * 2}});
下面是它的一些 API:
-
{$push: array}
===> Array.push() -
{$unshift: array}
===> Array.unshift() -
{$splice: array of arrays}
===> Array.splice -
{$set: any}
===> obj.a = 1叮喳,給對象某個元素賦值 -
{$toggle: array of strings}
toggles a list of boolean fields from the target object. -
{$unset: array of strings}
remove the list of keys in array from the target object. -
{$merge: object}
合并對象 - `{$apply: function} 通過函數將一個值轉為另外一個值被芳。
-
{$add: array of objects}
為 Map 或者 Set 添加一個值 -
{$remove: array of strings}
從 Map 或者 Set 移除一個值
我的場景
我有這么一個對象:
const data = [
{
id: 1,
name: '已解散',
tasks: [
{
id: 1,
text: 'Write a cool JS library'
},
{
id: 2,
text: 'Make it generic enough'
},
{
id: 3,
text: 'Write README'
}
]
},
{
id: 2,
name: '已刪庫',
tasks: [
{
id: 4,
text: 'Create some examples'
},
{
id: 5,
text: 'Spam in Twitter and IRC to promote it (note that this element is taller than the others)'
}
]
},
{
id: 3,
name: '已跑路',
tasks: [
{
id: 6,
text: '???'
},
{
id: 7,
text: 'ABC'
},
{
id: 8,
text: 'DDD'
},
{
id: 9,
text: 'AAA'
}
]
},
{
id: 4,
name: '已開源',
tasks: [
{
id: 10,
text: 'SSS'
},
{
id: 11,
text: 'VVV'
}
]
}
]
我需要將 data[i].tasks 里面的值重新排序或者移動(可以想象成看板的樣子)。
image.png
下面是更新方式:
let TempData = update(data, {
[fromColumnIndex]: {
issues: issues =>
update(issues, {
$splice: [[fromIssueIndex, 1]]
})
}
})
TempData = update(TempData, {
[toColumnIndex]: {
issues: issues =>
update(issues, {
$splice: [[toIssueIndex, 0, TempIssue]]
})
}
})
setData(TempData)
可以看到馍悟,setData() 里面用了多次 update 函數來操作 data 中的 tasks 數組畔濒。并且 update 的第二個對象中可以有多個屬性來同時操作對象的不同屬性的變化。
最后
immutability-helper
在處理復雜對象的時候的確要比用原生 API 修改赋朦,然后深拷貝一個新的對象優(yōu)雅很多篓冲。