Плоский список с разбивкой на страницы результатов Причина повторной визуализации при добавлении дополнительных данных с помощью Redux

Я пытаюсь отобразить список информации с сервера (результаты с разбивкой на страницы) при реагировании на родной с помощью плоского списка

Проблема заключается в том, что при загрузке второй партии результатов всегда выполняется повторная визуализация всего списка.

Компонент плоского списка

<FlatList
          data={_.size(this.props.search.getIn(['userInfoList','data'])) > 0 ? this.props.search.getIn(['userInfoList', 'data']).toJS() : []}
          renderItem={({item, index}) => this._renderResult(item, index)}
          keyExtractor={(item, index) => index.toString()}
          ListFooterComponent={()=>this._flatlistLoader()}
          ref={(ref) => { this.flatListRef = ref; }}
          ListEmptyComponent={()=>this._emptyList()}
          onEndReachedThreshold={0.5}
          onEndReached={() => this.loadMore()}
          onRefresh={() => this.refreshList()}
          refreshing={this.props.search.userInfoList.isRefreshing}
          initialNumToRender={8}
          maxToRenderPerBatch={5}
        />

функция shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState){
    return !_.isEqual(nextProps, this.props)
  }

Функция _renderResult (item, index), возвращающая чистый компонент InfoBox

_renderResult(item,index){
    return(
      <InfoBox key={index} item={item}/>
    )
  }

это часть моей функции действия после запроса данных с сервера

if(res.status == 200){
                    let newArr = []
                    getState().search.getIn(['userInfoList','data']).map((val) => {
                      newArr.push(val)
                    })
                    res.json.data.data.map((val) => {
                      newArr.push(val)
                    })
                    
                    dispatch(setInfoListResult(newArr))
                  }

тогда редуктор выглядит так

case SET_INFO_LIST_RESULT:
      return state.setIn(['userInfoList', 'data'], fromJS(action.newArr))

Мое начальное состояние import {Record, List, Map} из 'неизменяемого'

var InitialState = Record({
...
userInfoList: new (Record({
    userid:null,
        total: null,
        lastPage: null,
        data : [],
        perPage : null,
        currentPage : null,
        nextPageUrl: null,
        prevPageUrl:null,
        prevScene:null,
        isFetching:false,
        isRefreshing:false,
        hasError:false,
        hasMoreError:false,
        errorMsg:'',
    }))(),
})

Я помещаю console.log (item.id) в InfoBox (PureComponent), когда плоский список начинает загружать вторую страницу, он повторно отображает весь список 2 раза и получает предупреждение

VirtualizedList: у вас есть большой список, который медленно обновляется - убедитесь, что ваша функция renderItem отображает компоненты, соответствующие лучшим практикам производительности React, например PureComponent, shouldComponentUpdate и т. Д. ', {Dt: 4913, prevDt: 2441, contentLength: 11064}

Что-то не так с тем, как я обновляю список редуктора, вызывающего повторную визуализацию? Есть идеи, как это исправить?


person Tom Kur    schedule 27.09.2020    source источник


Ответы (1)


.toJS() преобразует неизменяемую коллекцию в новый объект JavaScript. Поэтому всякий раз, когда ваш компонент запускает render(), он генерирует новый объект и запускает рендеринг FlatList.

Кроме того, toJS выполняет глубокое преобразование. Ваши записи снова являются простыми изменяемыми объектами javascripts. Используйте toArray, если вам нужно только превратить коллекцию в массив.

Как правило, вам следует избегать преобразования коллекций в любом месте, это делает immutablejs бесполезными и плохо влияет на производительность на огромных наборах данных. Конечно, некоторые компоненты требуют использования собственных массивов. Возможно, вы захотите использовать какую-то мемоизацию для этих случаев, например React.memo, memoize-one, повторно выбрать, повторно повторно выбрать

уменьшить количество звонков до

person dube    schedule 12.10.2020