Добавление и удаление данных и подсчет с помощью useContext - React - Typescript

Я пытаюсь понять useContext на том, что, как мне казалось, было бы тривиальным примером ...

Я помещаю здесь не весь код, а только соответствующие фрагменты, полный код находится на codeandbox

У меня есть страница с двумя компонентами. Слева список. Справа контейнер. Когда я нажимаю кнопку «добавить» под своими элементами, они появляются в контейнере компонентов справа.

После этого можно щелкнуть кнопку отправки в контейнере списка, который направляется к другому компоненту со списком элементов. Оттуда можно убирать предметы.

Я делаю все, чтобы научиться делиться свойствами по всему приложению React. У меня несколько проблем:

  1. Когда я добавляю элемент, если имя уже включено. Я не хочу показывать это десять раз. Вместо этого я хочу отобразить его один раз, а затем показать, сколько раз он был добавлен рядом с ним. Мне сложно сделать это из-за того, как здесь работает setItemList:
  const addItem = useCallback((item) => {
    setCounter((prev) => ({
      ...prev,
      [item.name]: (prev[item.name] || 0) + 1
    }));
    setItemList((prev) => [...prev, item]);
  }, []);

И вот как я добавляю в свой компонент List:

  const addItemToItemList = (item: Item) => {
    /*if (!itemList.includes(item))*/ addItem(item);
  };

Я прокомментировал оператор if, чтобы иметь возможность добавлять элемент более одного раза, но затем он появляется снова и снова, а не только один раз (со счетчиком рядом с ним)

  1. Моя вторая проблема в том, что я не знаю, как получить доступ ко второму счетчику. Я даже не знаю, как получить к нему доступ с помощью простого console.info ...

  2. Наконец, на данный момент, если я добавляю одно и то же три раза в свой контейнер списка, а затем отправляю на последней странице, когда я нажимаю удалить, он удаляет их все сразу, тогда как я, очевидно, хочу удалить только один. Я думаю, это потому, что мой removeItem работает с именем, но я не могу придумать другого способа реализовать это ...

  const removeItem = useCallback(
    (itemName) =>
      setItemList((prev) => prev.filter((it) => it.name !== itemName)),
    []
  );

В любом случае, я с нетерпением жду советов и подсказок. Наслаждаюсь путешествием по React Hooks. Спасибо!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
20
2

Ответы 2

Здесь есть несколько архитектурных проблем:

Во-первых, если вы хотите подсчитать, сколько раз элемент был добавлен в список, но не хотите добавлять его несколько раз, вы не можете выполнить проверку при вызове addItem(), так как вы также увеличиваете счетчик внутри этой функции. . Вместо этого вы должны проверить наличие дубликатов в setItemList():

setItemList((prev) => prev.includes(item) ? prev : [...prev, item])

Во-вторых, я не понимаю, где вы хотите получить доступ ко второму счетчику, если вы имеете в виду в контейнере рядом с item.name, тогда это так же просто, как просто получить его из контекста, как вы это сделали с itemList:

const { itemList, counter } = useContext(ItemListContext);

// ...
<li key = {i}>{counter[item.name]} - {item.name}</li>
// ...

Что касается вашего третьего пункта, вы захотите использовать счетчик внутри метода, чтобы уменьшать его каждый раз, когда он вызывается, и удалять элемент только в случае counter == 0. Не забудьте добавить counter в список зависимостей useCallback, иначе вы всегда будете работать с устаревшим значением.

Я отредактировал вашу песочницу здесь для достижения желаемого результата, используя аналогичную реализацию и массив count, увеличивая его при добавлении элемента

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