Странное поведение на карте массива после обновления состояния - PullRequest
1 голос
/ 08 апреля 2020

Надеюсь, у вас все хорошо в нынешних условиях! Сейчас я работаю с Firebase и ReactJS и столкнулся со странным поведением при обновлении состояния в реакции и функциональности карты массива в JavaScript. Приведенный ниже код показывает мою логику c для прослушивания обновлений из базы данных firestore:

listenForContentChanges = async () => {
  let content = [];
  await db.collection('clients').doc(this.props.client)
    .collection('projects').doc(this.props.id)
    .collection('content').orderBy('created').onSnapshot(querySnapshot => {
      querySnapshot.docChanges().forEach(async change => {
        if (change.type === 'added') {
          content.push({
            id: change.doc.id,
            uploaded: change.doc.data().created.seconds
          });
        }
        if (change.type === 'removed') {
          content = content.filter(arrayItem => arrayItem.id !== change.doc.id);
        }
      });
      this.setState({
        content: content,
        addingContent: false
      });
    });
}

Как видите, массив заполняется информацией о содержимом, а именно идентификатором документа и полем содержит время в секундах, когда этот документ был создан. Это возвращает мне массив:

0: {id: "SZ4f0Z27rN2MKgXAlglhZVKDsNpKO6", uploaded: 1586323802}

Мне нужно, чтобы этот массив был отсортирован так, чтобы первым был самый последний документ, и потому что Firebase не предлагает его в качестве параметра запроса (вы можете только sortBy и не изменять направление ) Я копирую массив в новый массив, а затем вместо этого l oop, чтобы получить все в правильном порядке:

const sortedArr = [...this.state.content];
sortedArr.reverse();
/// IN THE RETURN: ///
{sortedArr.map((content, index) => (
   <Content key={index} />
))}

Это работает нормально, без проблем. Моя проблема в том, что теперь, когда добавляется новый элемент / один берется из массива состояний this.state.content, и компонент перерисовывается, я наблюдаю странное поведение, когда последние элементы вместо отображения новых данных, кажется, дублируют себя , Ниже приведен пример временной шкалы: Steps of a new document being added to array Как вы можете видеть, когда в firestore добавляется новый документ, код, показанный выше, корректно срабатывает, помещая новый элемент массива в состояние и повторно отображая компонент. Для тех, кто заинтересован, да, состояние корректно обновляется, это то, что регистрируется внутри функции рендеринга после обновления состояния:

0: {id: "x07yULTiB8MhR6egT7BW6ghmZ59AZY", uploaded: 1586323587}
1: {id: "SZ4f0Z27rN2MKgXAlglhZVKDsNpKO6", uploaded: 1586323802}

Вы можете видеть, что индекс 1 является новым, который является документом это было добавлено. Затем это переворачивается и отображается в функции return() render(), но вызывает странное поведение, показанное на рисунке выше. Любая помощь в том, что может быть причиной, будет большой помощью, я уже некоторое время бьюсь головой о стену!

1 Ответ

2 голосов
/ 08 апреля 2020

Использование индекса массива в качестве ключа реакции завершается неудачно, когда рендеринг массива изменяется (т. Е. Нестабильно). React видит новую длину, но ключ для первого элемента остается тем же, поэтому он выдает при повторном рендеринге (, даже если это новый элемент ).

Вместо этого попробуйте всегда используйте уникальные ключи в вашем наборе данных, например, свойство id.

{sortedArr.map((content, index) => (
   <Content key={content.id} />
))}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...