【问题标题】:Update deeply nested object property in immutableJS list更新 immutableJS 列表中深度嵌套的对象属性
【发布时间】:2019-02-03 12:19:52
【问题描述】:

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

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

在此列表中,我想更新项目 ID 200 的项目名称。虽然我可以通过查找它们的索引来更新简单的一级对象数组,但我不知道如何在 immutableJS 中从这个开始。

【问题讨论】:

  • 你很可能想要使用 immutable 的 updateIn:facebook.github.io/immutable-js/docs/#/updateIn
  • 我知道我需要这样的东西,但不知道如何完成它
  • updateIn 上的文档有各种示例,在 SO/google 中搜索“immutablejs updateIn”将为您提供很多示例。

标签: immutable.js immutablelist


【解决方案1】:

很久以前我有类似的东西......我使用了 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}
                                }
                            }))
                        }
                    }))
                }
            }))
        }
    }

【讨论】:

    【解决方案2】:

    我相信使用 Immutable 执行此操作的惯用方法是使用大量 .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一样简单:

    const newState = state.updateId(['projects', 200],
      project => project.set('projectName', 'NEW_PROJECT_NAME'));
    

    【讨论】:

      【解决方案3】:

      我建议您不要将 immutable.js 用于此类复杂的数据结构,或者将结构重构为简单的集合。否则不仅你会遭受维护地狱的痛苦,而且性能会差数百倍(但你可能仍然没有注意到它,这取决于你的应用程序)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多