带有分页结果的 Flatlist 在使用 Redux 附加更多数据时导致重新渲染
Flatlist with Paginated Result Cause Rerender when Appending More Data Using Redux
我正在尝试使用 flatlist 显示来自服务器的信息列表(分页结果)
问题似乎是在加载第二批结果时总是重新呈现整个列表。
平面列表组件
<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))
}
那么reducer是这样的
case SET_INFO_LIST_RESULT:
return state.setIn(['userInfoList', 'data'], fromJS(action.newArr))
我的初始状态
从 'immutable'
导入{记录、列表、地图}
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: You have a large list that is slow to update - make
sure your renderItem function renders components that follow React
performance best practices like PureComponent, shouldComponentUpdate,
etc.', { dt: 4913, prevDt: 2441, contentLength: 11064 }
我更新 reducer 列表的方式有问题导致重新渲染?知道如何解决这个问题吗?
.toJS()
将不可变集合转换为 new javascript 对象。因此,每当您的组件运行时 render()
,它都会生成一个新对象并触发 FlatList 的渲染。
此外,toJS进行深度转换。您的记录现在再次成为普通可变 javascripts 对象。如果您只需要将集合转换为数组,请使用 toArray。
您通常应该避免在任何地方转换集合,这会使 immutablejs 变得无用并且不利于大型数据集的性能。当然,有些组件要求您使用本机数组。您可能希望对这些情况使用某种记忆,例如React.memo, memoize-one, reselect, re-reselect
减少对
的调用量
我正在尝试使用 flatlist 显示来自服务器的信息列表(分页结果)
问题似乎是在加载第二批结果时总是重新呈现整个列表。
平面列表组件
<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))
}
那么reducer是这样的
case SET_INFO_LIST_RESULT:
return state.setIn(['userInfoList', 'data'], fromJS(action.newArr))
我的初始状态 从 'immutable'
导入{记录、列表、地图}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: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc.', { dt: 4913, prevDt: 2441, contentLength: 11064 }
我更新 reducer 列表的方式有问题导致重新渲染?知道如何解决这个问题吗?
.toJS()
将不可变集合转换为 new javascript 对象。因此,每当您的组件运行时 render()
,它都会生成一个新对象并触发 FlatList 的渲染。
此外,toJS进行深度转换。您的记录现在再次成为普通可变 javascripts 对象。如果您只需要将集合转换为数组,请使用 toArray。
您通常应该避免在任何地方转换集合,这会使 immutablejs 变得无用并且不利于大型数据集的性能。当然,有些组件要求您使用本机数组。您可能希望对这些情况使用某种记忆,例如React.memo, memoize-one, reselect, re-reselect
减少对
的调用量