在做项目时,很多时候服务端返回的接口嵌套很深,同时每一层是否存在或者为空都是不确定的。因此,为了获得内层的字段通常需要做多次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官方文档