Дублируйте элемент из массива, затем измените идентификатор

Я хочу дублировать элемент с помощью сращивания, но у меня возникли проблемы при изменении идентификатора. Мне нужен другой идентификатор для каждого элемента, но, хотя он дублируется, он сохраняет тот же идентификатор. Также идентификатор становится числом, но должен быть строкой.

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

Вывод: элемент дублируется, но идентификатор меняется для обоих одинаковых элементов и становится целым числом, а не строкой.

const duplicate_item = list.cards[index]; duplicate_item["id"] = list.cards.length + 1; вы меняете идентификатор оригинального предмета, это так и задумано? возможно, вы можете сделать неглубокую копию, например const duplicate_item = {...list.cards[index]};, но не можете сказать, достаточно ли поверхностной копии, не видя структуры данных
cmgchess 30.09.2023 18:16
stackoverflow.com/questions/29050004/…
cmgchess 30.09.2023 18:20

@cmgchess Кажется, ваше предложение работает! Спасибо

Mathieu 30.09.2023 20:38

круто, ты можешь опубликовать ответ, может быть

cmgchess 30.09.2023 20:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

Другие вопросы по теме