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 Réponses :
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 } } };
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: [] }, } };
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.
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.
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
ouitems
, 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.