1
votes

Comment diffuser des propriétés imbriquées dans Object?

J'ai cet objet ci-dessous. Je me demandais comment je pouvais sélectionner un élément spécifique et mettre à jour une propriété. Par exemple. Élément 1 Je souhaite ajouter une tâche dans le tableau.

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
      }
    };

J'ai actuellement

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: []
  },


3 commentaires

Il est très difficile de vous aider, car votre structure dans le premier bloc de code ne correspond pas à votre code. Votre structure n'a pas de colonnes ou items , votre code a les deux ...?


@ T.J.Crowder ce sont tous des articles désolés.


Veuillez corriger le premier bloc de code et fournir un exemple complet, pas seulement une partie de l'objet d'état.


3 Réponses :


0
votes

Vous devez utiliser la clé d'objet, c'est-à-dire item-1 , cloner ses propriétés et ajouter la nouvelle liste pour la clé de tâche. En bref, vous devez cloner à chaque niveau de l'objet avant de remplacer la clé que vous souhaitez mettre à jour

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


0 commentaires

1
votes

En supposant le point de départ:

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);

Si vous souhaitez ajouter une tâche au tableau task-1 de task sans modifier choses en place (ce qui est important dans l'état React), vous devez copier state , items , item-1 et item -1 task :

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

Exemple en direct:

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: []
      },
    }
};


0 commentaires

-1
votes

Dans lodadash, vous pouvez obtenir et définir un objet imbriqué à partir d'un objet, voici ma propre implémentation:

//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')
  )
);

Vous pouvez mettre le get et le set dans une bibliothèque et cela faciliterait la définition de valeurs profondément imbriquées aux yeux des futurs lecteurs de votre code.


1 commentaires

Vous pourriez envisager de changer l'ouverture en "Voici un utilitaire pour plonger profondément dans une structure d'objet inspirée par lodash (mais ne pas l'utiliser):" ou quelque chose.