我在下面有这个对象。我想知道如何选择特定项目并更新属性。例如。项目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: []
},
我目前有
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
}
};
答案 0 :(得分:1)
您需要使用对象键,即item-1
并为其克隆属性,并为任务键添加新列表。简而言之,您需要先克隆对象的每个级别,然后再覆盖要更新的密钥
const newState = {
...state,
items: {
...state.items,
'item-1': {
...state.items['item-1'],
task: newTaskList
}
}
};
答案 1 :(得分:1)
假设起点:
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: []
},
}
};
如果您想在item-1
的{{1}}数组中添加任务而不修改原位(这在React状态下很重要),则必须复制task
,{{ 1}},state
和items
的{{1}}:
item-1
实时示例:
item-1
答案 2 :(得分:-1)
在lodadash中,您可以从对象获取并设置嵌套对象,这是我自己的实现:
//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')
)
);
您可以将get和set放在一个库中,这会使设置深层嵌套的值更容易在以后的代码读者中看到。