Реагируйте, добавляя новый элемент для каждого `null` в списке элементов при каждом повторном рендеринге

Если вы сопоставляете массив для элементов рендеринга и в результирующем массиве элементов у вас есть null, а затем 2 или более элементов с одним и тем же ключом, при каждом повторном рендеринге React будет добавлять еще один элемент в DOM, как эти два.

Вот минимальный код для воспроизведения:

const LIST = [{ id: 2, done: true },{ id: 1 },{ id: 1 }];

function App() {
  const forceUpdate = React.useState()[1];
  return LIST.map(({ id, done }, i) => {
    if (done) {
      return null;
    }
    return (
      <p key={id} onMouseEnter={forceUpdate}>
        Index: {i}
      </p>
    );
  });
}

А вот тот же код в CodeSandbox для игры с ним: https://codesandbox.io/s/8kqxr

Обратите внимание, что когда вы наводите курсор на список (и, следовательно, вызываете повторную визуализацию), React добавляет дополнительный элемент в результирующий DOM.

Проблемы можно избежать одним из следующих способов:

  • обеспечение уникального идентификатора

  • перемещение всех null элементов в конец списка

  • убедиться, что нет null элементов

Я знаю, что React НЕ поддерживает элементы с одним и тем же ключом и предупреждает, что их использование может привести к ошибкам, но мне все еще интересно, что именно вызывает это? Может ли кто-нибудь с глубоким знанием согласования JSX и React объяснить мне это?


person Leo Brdar    schedule 15.05.2019    source источник
comment
Функция JavaScript Array.map() вернет массив с одинаковым количеством элементов, независимо от того, являются ли какие-либо элементы пустыми или нулевыми.   -  person Bryan Elliott    schedule 15.05.2019
comment
Ссылка на песочницу не работает, но вы можете добавить return LIST.map(same stuff you have).filter(item => item != null), чтобы удалить нулевые элементы.   -  person Shawn Pacarar    schedule 15.05.2019
comment
@BryanElliott да, я недостаточно ясно выразился в своем вопросе. Массив содержит правильные элементы, но способ, которым React различает виртуальный и реальный DOM, нарушен и приводит к отображению дополнительных элементов.   -  person Leo Brdar    schedule 16.05.2019
comment
@ShawnPacarar Да, но JSX должен игнорировать элемент null в любом случае. По какой-то причине кажется, что он не полностью игнорирует это. Это то, что я пытаюсь выяснить здесь, это скорее вопрос, почему это происходит, а не как это исправить.   -  person Leo Brdar    schedule 16.05.2019


Ответы (1)


Я полагаю, что реакция использует ключи, чтобы определить, какие компоненты обновлять, поскольку индекс: 1 и индекс: 2 имеют один и тот же ключ, который он запутался, чтобы изменить, поэтому он смотрит на второе (последнее вхождение ключа) в этом случае Индекс :2 и заменяет его новыми повторно визуализированными данными

person akshay kishore    schedule 16.05.2019