Я хочу дублировать элемент с помощью сращивания, но у меня возникли проблемы при изменении идентификатора. Мне нужен другой идентификатор для каждого элемента, но, хотя он дублируется, он сохраняет тот же идентификатор. Также идентификатор становится числом, но должен быть строкой.
const duplicateCard = (index, listId) => {
const list = data.lists[listId];
const duplicate_item = list.cards[index];
duplicate_item["id"] = list.cards.length + 1;
list.cards.splice(0, 0, duplicate_item);
const newState = {
...data,
lists: {
...data.lists,
[listId]: list,
},
};
setData(newState);
window.localStorage.setItem("datt", JSON.stringify(newState));
};
Вывод: элемент дублируется, но идентификатор меняется для обоих одинаковых элементов и становится целым числом, а не строкой.
@cmgchess Кажется, ваше предложение работает! Спасибо
круто, ты можешь опубликовать ответ, может быть



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


splice — изменяемое действие. В React вы всегда создаете новые данные —
const duplicateCard = (index, listId) => {
setData(data => {
const list = data.lists[listId]
return {
...data,
lists: {
...data.lists,
[listId]: {
...list,
cards: [
{
...list.cards.at(index),
id: list.cards.length // you need better id generator
},
...list.cards,
]
},
},
})
}
Настоящий государственный кошмар вы себе создали!
Вы можете попытаться управлять этим с помощью общей функции, например update -
function update(key, func) {
return t => { switch (t.constructor) {
case Array:
return [...t.slice(0, key), func(t.at(key), key, t), ...t.slice(key + 1)]
case Object:
return {...t, [key]: func(t[key], key, t)}
default:
throw Error(`update called on non-object: ${t}`)
}}
}
Теперь вашу функцию duplicateCard можно улучшить. Примечание newId является обязанностью звонящего -
const duplicateCard = (index, listId, newId) => {
setData(
update("lists",
update(listId,
update("cards", cards => [
{ ...cards.at(index), id: newId },
...cards,
])
)
)
)
}
Это большой шаг в правильном направлении, и, возможно, вы увидите закономерность. Тем не менее, это кажется большим усилием.
Оказывается, неизменяемые структуры данных имеют хорошо продуманные и протестированные инструменты для работы с ними. Посмотрите такие библиотеки, как ImmutableJS.
Как предполагает @cmgchess, это работает:
const duplicateCard = (index, listId) => {
const list = data.lists[listId];
const duplicate_item = {...list.cards[index]};
duplicate_item["id"] = (list.cards.length + 1).toString();
list.cards.splice(0, 0, duplicate_item);
const newState = {
...data,
lists: {
...data.lists,
[listId]: list,
},
};
setData(newState);
window.localStorage.setItem("datt", JSON.stringify(newState));
};
const duplicate_item = list.cards[index]; duplicate_item["id"] = list.cards.length + 1;вы меняете идентификатор оригинального предмета, это так и задумано? возможно, вы можете сделать неглубокую копию, напримерconst duplicate_item = {...list.cards[index]};, но не можете сказать, достаточно ли поверхностной копии, не видя структуры данных