更新immutableJS列表中的深层嵌套对象属性

时间:2018-08-28 19:35:31

标签: immutable.js immutablelist

我具有以下不可变列表的层次结构:

fromJS({
departments: [{
    departmentName: 'PHP',
    employees: [{
        employeeId: 1000,
        employeeName: 'Manish',
        projects: [{
            projectId: 200,
            projectName: 'ABC'
        },
        {
            projectId: 300,
            projectName: 'DEF'
        }]
    }]
}]
})

在此列表中,我要更新项目ID为 200 的项目名称。尽管我可以通过找到对象的索引来更新对象的简单一级数组,但是我不知道如何在immutableJS中从该数组开始。

3 个答案:

答案 0 :(得分:0)

我很久以前就有类似的东西...我使用了flatMap函数。最终,我修改了状态结构,因为维护此代码是一场噩梦。

updateProduct = (id, newName, data) => {
        return {
            departments: Immutable.flatMap(data.departments, (department => {
                return {
                    ...department,
                    employees: Immutable.flatMap(department.employees, (employee => {
                        return {
                            ...employee,
                            projects: Immutable.flatMap(employee.projects, (project => {
                                if (project.projectId == id) {
                                    return {
                                        ...project,
                                        projectName: newName
                                    }
                                }
                                else {
                                    return {...project}
                                }
                            }))
                        }
                    }))
                }
            }))
        }
    }

答案 1 :(得分:0)

我相信使用Immutable进行此操作的惯用方式是使用大量的readonly.map调用:

.update

const state = fromJS(/*...*/);
const newState = state.update('departments',
  departments => departments.map(
    department => department.update('employees',
      employees => employees.map(
        employee => employee.update('projects',
          projects => projects.map(
            project => project.get('projectId') === 200 ?
            project.set('projectName', 'NEW_PROJECT_NAME') :
            project
          ))))));
const state = Immutable.fromJS({
  departments: [{
    departmentName: 'PHP',
    employees: [{
      employeeId: 1000,
      employeeName: 'Manish',
      projects: [{
          projectId: 200,
          projectName: 'ABC'
        },
        {
          projectId: 300,
          projectName: 'DEF'
        }
      ]
    }]
  }]
})

const newState = state.update('departments',
  departments => departments.map(
    department => department.update('employees',
      employees => employees.map(
        employee => employee.update('projects',
          projects => projects.map(
            project => project.get('projectId') === 200 ?
            project.set('projectName', 'NEW_PROJECT_NAME') :
            project
          ))))));

console.log(newState);

处理深度嵌套的数据很烦人。我认为,只要稍微简化一下数据结构,就可以简化生活。以这个结构为例:

<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.min.js"></script>

使用这样的结构,您对原始问题的答案就像一个const state = fromJS({ departments: [{ employeeIds: [ 1000 ] }], employees: { 1000: { employeeId: 1000, employeeName: 'Manish', projectIds: [ 200, 300 ] } }, projects: { 200: { projectId: 200, projectName: 'ABC' }, 300: { projectId: 300, projectName: 'DEF' } } }); 一样简单:

updateIn

答案 2 :(得分:0)

我建议您不要将immutable.js用于此类复杂的数据结构,或将结构重构为简单的集合。否则,不仅会遭受维护麻烦,而且性能会恶化数百倍(但仍然可能不会引起注意,取决于您的应用程序。)