React-Native ScrollView потерял позицию на setState

Мне нужно изменить состояние строки в ScrollView (то же самое в ListView), но использование setState компонента заставляет прокрутку сбрасывать ее положение вверх.

          <ScrollView
        {...this.panResponder.panHandlers}
        bounces={false}
        onScroll={() => {
          this.scrollIsScrolling = true;
        }}
        onTouchEnd={() => {
          this.scrollIsScrolling = false;
        }}
        onMomentumScrollEnd={() => {
          this.scrollIsScrolling = false;
        }}
        scrollEnabled={this.state.scrollEnabled}
        removeClippedSubviews={false}
        enableEmptySections
        style={styles.listView}
      >
        {this.props.settings.map((setting, i) => {
          return (
            <IntegrationSlideupCell
              key={i}
              title={setting.title}
              selected={this.state.selectedSetting === i}
              selectedGradient={this.props.integration.selectedGradient}
              onPress={() => {
                this.setState({ selectedSetting: i });
              }}
            />
          );
        })}
      </ScrollView>

UPD: Удаление пользовательских обработчиков panHandlers, onScroll, onTouchEnd, onMomentumScrollEnd и других свойств не имеет значения. Единственное, что вызывает его setState.


person Jlexyc    schedule 02.10.2017    source источник
comment
вы пытались сохранить размер своего содержимого onContentSizeChange в вашем просмотре прокрутки?   -  person Ganesh Cauda    schedule 02.10.2017
comment
Нет, не знал. Но режим прокрутки iOS (собственный) сохраняет позицию, даже если размер был изменен. Так что я ожидал того же. Но попробую, спасибо за совет.   -  person Jlexyc    schedule 02.10.2017
comment
Почему бы не ввести scrollToIndex() функциональность?   -  person Khalil Khalaf    schedule 02.10.2017
comment
В настоящее время исправлено путем сохранения смещения перед использованием setState. Но продолжайте расследование.   -  person Jlexyc    schedule 02.10.2017


Ответы (1)


Используя подход со смещением, если IntegrationSlideupCell задана фиксированная высота, вы можете выполнить смещение по этой ширине и сохранить смещение для состояния

this.state = {
    contentOffset: {y: 0},
}

function handlePress() {
   offset = HEIGHT_OF_CONTAINER;
   newOffset = this.state.contentOffset.y + offset;    
   this.setState({contentOffset: {y: newOffset}, selectedSetting: i });
} 

          <ScrollView
    {...this.panResponder.panHandlers}
    bounces={false}
    contentOffset={this.state.contentOffset}
    onScroll={() => {
      this.scrollIsScrolling = true;
    }}
    onTouchEnd={() => {
      this.scrollIsScrolling = false;
    }}
    onMomentumScrollEnd={() => {
      this.scrollIsScrolling = false;
    }}
    scrollEnabled={this.state.scrollEnabled}
    removeClippedSubviews={false}
    enableEmptySections
    style={styles.listView}
  >
    {this.props.settings.map((setting, i) => {
      return (
        <IntegrationSlideupCell
          key={i}
          title={setting.title}
          selected={this.state.selectedSetting === i}
          selectedGradient={this.props.integration.selectedGradient}
          onPress={handlePress.bind(this)}
        />
      );
    })}
  </ScrollView>
   
   
person samuel    schedule 06.08.2020