Управление копией массива (созданной с помощью оператора распространения) изменяет исходный массив в памяти - PullRequest
0 голосов
/ 07 августа 2020

https://codesandbox.io/s/chart-3yx8p

Компонент «Диаграмма» состоит из 3-х диаграмм, наложенных друг на друга:

  • линейная диаграмма - Компонент «VictoryLine»
  • 2 точечные диаграммы - компоненты «VictoryScatter»

Линейный график просто отображает линию. Первая диаграмма рассеяния отображает синие кружки над каждой точкой на линии - мы назовем ее «BlueScatter». Эти 2 принимают одни и те же данные stati c. Вторая диаграмма рассеивания отображает черные точки внизу - мы назовем ее «BlackScatter». Данные для BlackScatter находятся в состоянии, которое необходимо изменить.

Каждый раз, когда вы наводите курсор на один из синих кружков, происходят две вещи:

  • отображается всплывающая подсказка
  • черная точка под этим кругом перемещается на полпути вверх

Когда ваша мышь покидает круг, всплывающая подсказка исчезает, и точка предназначена для перемещения вниз. Однако последнего не происходит ...

Когда вы наводите указатель на кружок, "активная" опора, переданная компоненту метки этого круга, принимает значение true - и false, когда указатель мыши покидает его. Компонент «Подсказка» устанавливается в качестве метки для каждой точки на BlueScatter, поэтому подсказка получает эту опору. Tooltip - это просто невидимый SVG, используемый для привязки всплывающей подсказки пользовательского интерфейса материала. Обработчики событий BlueScatter управляют этим logi c (см. Файл констант). Во всплывающей подсказке я использую реквизиты, переданные из Chart, чтобы изменить координаты данных BlackScatter в этом индексе.

С учетом всего сказанного: В диаграмме я распределяю INITIAL_HOVER_DATA в массив в состоянии для установки данных BlackScatter. Во всплывающей подсказке я снова помещаю эту константу в пустой массив, который будет использоваться в следующем операторе if. В прошлом мне всегда удавалось использовать оператор распространения для создания копии массива, но по какой-то причине кажется, что строка 14 всплывающей подсказки манипулирует исходной константой в памяти. Вот почему черные точки не возвращаются в исходное положение. Почему это происходит? Раскомментируя строку 16, все работает так, как задумано, но теоретически в этом нет необходимости.

Между прочим - если кто-нибудь может предложить лучший способ достижения этой же функциональности, я бы хотел получить обратную связь!

TL; DR: манипулирование копией массива INITIAL_HOVER_DATA изменяет исходный массив в памяти.

1 Ответ

0 голосов
/ 07 августа 2020

Проблема

Даже если вы неглубоко копируете массив, newHoverData[index].y = yValue / 2; является мутацией состояния, поскольку вы также не копируете каждый обновляемый элемент. Каждый элемент по-прежнему относится к элементу в исходном массиве.

Решение

Неглубоко скопируйте массив и элемент, который вы хотите обновить

useEffect(() => {
  const { y: yValue } = data[index];
  setScatterHoverData(
    INITIAL_HOVER_DATA.map((el, i) =>
      i === index && active
        ? {
            ...el,
            y: yValue / 2
          }
        : el
    )
  );
}, [active]);

Изменить диаграмму: манипулирование-копированием-массивом-созданным-через-оператор-распространения-изменения-исходный-массив-в

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...