在做項目時,很多時候服務端返回的接口嵌套很深,同時每一層是否存在或者為空都是不確定的。因此,為了獲得內層的字段通常需要做多次if判斷來進行容錯,比如下面的這個接口格式:
{
"data": {
"Relations": [
{
"Instances": [
{
"InstanceId": "xx",
"EipList": ["21.107.32.xx" ]
}, {
"InstanceId": "xxxx",
"EipList": ["21.107.33.xx"]
}
],
"Domain": "test.com"
},
......
]
}
}
現在需要取出每個 Domain為“test.com”的EipList中的IP集合,在不使用immutable的條件下,通常我們會這么去寫(這里采用新語法):
let allEips = [];
if (data.Relations && data.Relations.length > 0) {
let relations = data.Relations;
let target = relations.find((elem) => {
return elem.Domain === "test.com"
});
if (target && target.Instances && target.Instances.length > 0) {
let instances = target.Instances;
instances.forEach((inst) => {
let eipList = inst.EipList;
if (eipList && eipList.length > 0) {
allEips.push(...eipList);
}
});
}
}
allEips = [...new Set(allEips)]; // 去重
console.log(allEips); // 輸出 [ '21.107.32.xx', '21.107.33.xx' ]
現在我們引入immutable.js來處理這個問題:
import { fromJS, List, Map } from 'immutable';
const immutableData = fromJS(data);
const target = immutableData.get('Relations', List()).find(relation => relation.get('Domain') === "test.com", null, Map());
const eips = target.get('Instances', List()).map(inst => inst.get('EipList', List())).flatten(true);
const allEips = eips.toJS();
console.log(allEips); // 輸出 ["21.107.32.xx", "21.107.33.xx"]
Bingo!!! 深層嵌套不見了,整個代碼架構變成了扁平化的結構,因為用immutable.js可以直接訪問深層字段,并且可以在每一層設置默認值。
使用immutable.js實現深層字段訪問和容錯處理其實是大材小用,其真正的牛逼之處在于持久化數據結構,在使用舊數據創建新數據時,能夠保證舊數據可用且不變,可以給React應用帶來極大的性能提升。
有興趣的話可以閱讀下面的網站進行深入了解:
Immutable 詳解及 React 中實踐
immutable官方文檔