简体   繁体   English

如何在 Object 中传播嵌套属性?

[英]How to spread nested properties in Object?

I have this object below.我在下面有这个 object。 I was wondering how I can select a specific item and update a property.我想知道如何 select 特定项目并更新属性。 For example.例如。 Item 1 I want to add a task in the array.项目 1 我想在数组中添加一个任务。

item: {
  'item-1': {
    id: 'item-1',
    title: 'To do',
    task: ['task-1', 'task-2', 'task-3', 'task-4']
  },
  'item-2': {
    id: 'item-2',
    title: 'In progress',
    task: []
  },

I currently have我目前有

const getItem = {...state.items['item-1']}
const newTaskList = [...getItem.task, newTask.id]

const newState = {
      ...state,
      items: {
        ...state.items,
        //How do I spread new array correctly in item 1?
        //...state.items['item-1'].task
      }
    };

Assuming the starting point:假设起点:

let state = {
    items: {
      'item-1': {
        id: 'item-1',
        title: 'To do',
        task: ['task-1', 'task-2', 'task-3', 'task-4']
      },
      'item-2': {
        id: 'item-2',
        title: 'In progress',
        task: []
      },
    }
};

If you want to add a task to item-1 's task array without modifying things in place (which is important in React state), you have to copy state , items , item-1 , and item-1 's task :如果您想将任务添加到item-1task数组而不修改内容(这在 React 状态中很重要),您必须复制stateitemsitem-1item-1task

let newState = {
    ...state,
    items: {
        ...state.items,
        'item-1': {
            ...state.items['item-1'],
            task: [...state.items['item-1'].task, newTask]
        }
    }
};

Live Example:现场示例:

 let state = { items: { 'item-1': { id: 'item-1', title: 'To do', task: ['task-1', 'task-2', 'task-3', 'task-4'] }, 'item-2': { id: 'item-2', title: 'In progress', task: [] }, } }; let newTask = "task-4"; let newState = {...state, items: {...state.items, 'item-1': {...state.items['item-1'], task: [...state.items['item-1'].task, newTask] } } }; console.log(newState);

You need to use the object key ie item-1 and clone the properties for it and add the new list for the task key.您需要使用 object 密钥,即item-1并为其克隆属性并为任务密钥添加新列表。 In short you need to clone at each level of the object before overriding the key that you wish to update简而言之,您需要在覆盖您希望更新的密钥之前在 object 的每个级别进行克隆

const newState = {
  ...state,
  items: {
    ...state.items,
    'item-1': {
         ...state.items['item-1'],
         task: newTaskList
     }
  }
};

In lodadash you can get and set nested object from an object, here is my own implementation of it:在 lodadash 中,您可以从 object 获取和设置嵌套的 object,这是我自己的实现:

 //helper to get prop from object const get = (object, path, defaultValue) => { const recur = (object, path) => { if (object === undefined) { return defaultValue; } if (path.length === 0) { return object; } return recur(object[path[0]], path.slice(1)); }; return recur(object, path); }; //helper to set nested prop in object const set = ( state, statePath, modifier ) => { const recur = (result, path) => { const key = path[0]; if (path.length === 0) { return modifier(get(state, statePath)); } return Array.isArray(result)? result.map((item, index) => index === Number(key)? recur(item, path.slice(1)): item ): {...result, [key]: recur(result[key], path.slice(1)), }; }; const newState = recur(state, statePath); return get(state, statePath) === get(newState, statePath)? state: newState; }; let state = { items: { 'item-1': { id: 'item-1', title: 'To do', task: ['task-1', 'task-2', 'task-3', 'task-4'], }, 'item-2': { id: 'item-2', title: 'In progress', task: [], }, }, }; console.log( set( state, ['items','item-1','task'], (tasks)=>tasks.concat('new task') ) );

You can put the get and set in a library and it would make setting deeply nested values easier on the eyes of future readers of your code.您可以将 get 和 set 放在一个库中,这将使您的代码的未来读者更容易设置深度嵌套的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM