React-native: Путаница с рендерингом rowHasChanged и ListView

Созданный на 4 февр. 2016  ·  3Комментарии  ·  Источник: facebook/react-native

Всем привет,

Работая над некоторыми улучшениями производительности, я обнаружил, что rowHasChanged не вызывается ни в одном из наших списков. Эти списки представляют собой списки с бесконечной прокруткой, а это означает, что когда вы дойдете до конца, он выберет больше элементов для отображения, а затем выгрузит их в список.

Кажется, что все записи в списке обновляются всякий раз, когда мы изменяем содержимое DataSource. У нас есть shouldComponentUpdate для всех строк, но, насколько я понял rowHasChanged , эти строки не нужно будет снова отображать.

Я создал простой пример, показывающий, как мы добавляем элементы в список: https://gist.github.com/janmonschke/c9c84b6050683da0c64f .

Что мы делаем в основном:

constructor() {
  // (...)
  this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
    console.log('rowHasChanged');
    return r1 !== r2;
  }});
  // (...)
}

onEndReached = () => {
  // append data to the end
  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.ds.cloneWithRows(setData)
  });
  console.log('onEndReached');
};

render() {
  return (
    <ListView
      dataSource={this.state.dataSource}
      renderRow={this.renderRow}
      onEndReached={this.onEndReached}
    />
  );
}

Но rowHasChanged никогда не регистрируется.

Я использую его как-то неправильно? Есть ли лучшие способы добавления в ListView?

Такое же поведение в 0.18.0 и 0.19.0

Самый полезный комментарий

Хорошо, нашел решение в: http://stackoverflow.com/a/33871118.

Очевидно, важно клонировать из правильного экземпляра DataSource;)

Таким образом, код из сути должен был быть:

  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(setData)
  });

Это похоже на ошибку, которая легко проникает в вашу кодовую базу. Интересно, правильное использование DataSource должно быть более подчеркнуто в документации.

Все 3 Комментарий

Эй, janmonschke, спасибо, что сообщили об этой проблеме!

React Native, как вы, наверное, слышали, становится очень популярным, и правда в том, что мы немного ошеломлены активностью вокруг него. У нас слишком много проблем, чтобы мы могли справиться с ними должным образом.

  • Если вы не знаете, как что-то сделать, или что- то работает не так, как вы ожидаете, но не уверены, что это ошибка , спросите в StackOverflow с тегом react-native или, чтобы узнать больше о взаимодействии в реальном времени, спросите в Discord в #react-нативный канал.
  • Если это запрос функции или ошибка , которую вы хотели бы исправить, сообщите об этом на странице Product Pains . Он имеет функцию ранжирования, которая позволяет нам сосредоточиться на наиболее важных проблемах, с которыми сталкивается сообщество.
  • Мы приветствуем четкие вопросы и PR, которые готовы к углубленному обсуждению. При необходимости предоставьте скриншоты и всегда указывайте версию React Native, которую вы используете. Спасибо за ваш вклад!

Хорошо, нашел решение в: http://stackoverflow.com/a/33871118.

Очевидно, важно клонировать из правильного экземпляра DataSource;)

Таким образом, код из сути должен был быть:

  setData = [...setData, ...genRandomSet()];
  this.setState({
    dataSource: this.state.dataSource.cloneWithRows(setData)
  });

Это похоже на ошибку, которая легко проникает в вашу кодовую базу. Интересно, правильное использование DataSource должно быть более подчеркнуто в документации.

Спасибо @janmonschke! Я согласен, у меня была куча просмотров, постоянно перерисовывающихся, и я не мог понять, почему это происходит и почему функция rowHasChanged никогда не вызывалась. 👊

Была ли эта страница полезной?
0 / 5 - 0 рейтинги