当onEndReached调用时,React Native(Redux)FlatList跳到列表顶部

时间:2018-10-04 11:53:00

标签: react-native redux react-native-flatlist

我在ReactNative中有一个FlatList,它可以从API中提取文章列表。在滚动时到达列表末尾时,将从API中拉出另一页文章,并将其附加到Redux reducer中的文章列表中。

FlatList设置为:

render() {
    return(
    <FlatList data={this.props.articles.articles} // The initial articles list via Redux state
        renderItem={this.renderArticleListItem} // Just renders the list item.
        onEndReached={this.pageArticles.bind(this)} // Simply calls a Redux Action Creator/API
        onEndReachedThreshold={0}
        keyExtractor={item => item.id.toString()}/>
   )};

使用React Redux连接功能将Redux'articles'状态对象映射到组件。相关的reducer(为简洁起见,删除了一些项目)如下所示:

/// Initial 'articles' state object
const INITIAL_STATE = {
    articles: [],
    loading: false,
    error: '',
    pageIndex: 0,
    pageSize: 10
};

export default(state = INITIAL_STATE, action) => {
switch(action.type){
    // The relevant part for returning articles from the API
    case ARTICLES_SUCCESS:
        return { ...state, loading: false, articles: state.articles.concat(action.payload.items), 
            pageIndex: action.payload.pageIndex, pageSize: action.payload.pageSize}
   default:
       return state;
   }
}

有效载荷是一个简单的对象-物品包含在action.payload.items数组中,并且有效载荷中还包含其他分页信息(对这个问题并不重要)。

一切正常,API返回正确的数据。

问题是,滚动时到达FlatList的末尾时,将调用API,将新文章拉细并附加到this.props.articles状态对象和FlatList中,但FlatList会跳转/滚动回到列表中的第一项。

我认为问题可能出在Redux reducer中如何返回状态,但是我不确定为什么。

使用concat是返回附加了新文章的新状态的正确方法吗?

3 个答案:

答案 0 :(得分:0)

您需要向listItem样式添加高度和宽度。冻结和跳跃可能是因为列表试图计算所有项目的大小,即使它们不显示也是如此。

您可以在https://github.com/facebook/react-native/issues/13727

中找到答案

答案 1 :(得分:0)

回答这个问题可能为时已晚,但是我遇到了完全相同的问题,即我的数据从redux服务到组件,并通过使组件成为普通的Component而非{{1} }允许我使用PureComponent生命周期挂钩方法。该方法对您的组件应如下所示:

shouldComponentUpdate

此方法(如果已实现)应返回一个布尔值,该值指示组件是否应该更新。我在这里所做的是在shouldComponentUpdate(nextProps) { if (this.props.articles === nextProps.articles) { return false; } return true; } 的内容未更改的情况下防止组件重新呈现。

希望这对您或其他可能遇到类似问题的人很有帮助。

答案 2 :(得分:0)

使用FlatList作为组件并添加数据作为道具会重新呈现整个内容,因此它会滚动到顶部。我建议直接在页面内使用它,并使用this.state而不是props

更改其数据