为啥 FlatList 在 React Native 中没有动态更新

Posted

技术标签:

【中文标题】为啥 FlatList 在 React Native 中没有动态更新【英文标题】:Why FlatList is not updating dynamically in React Native为什么 FlatList 在 React Native 中没有动态更新 【发布时间】:2018-11-10 06:58:39 【问题描述】:

我对本机反应非常陌生,我正在尝试动态更新列表。

下面是我的代码:

import React,  Component  from "react";
import  View, Text, StyleSheet, FlatList  from "react-native";
import  Tile, ListItem, List  from "react-native-elements";


export default class JoinSession extends Component 

    constructor() 
        super();

        this.state = 
            dataToRender: [ "id": "0", "name": "name0", "des": "des0" ]
        
    

    componentDidMount()    
        var counter = 0;
        const interval = setInterval(() => 
            try 
                var temp = 
                    "id": ++counter + "",
                    "name": "name" + counter,
                    "des": "des" + counter
                

                let tempArray = this.state.dataToRender;
                tempArray.push(temp);

                this.setState(
                    dataToRender: tempArray
                );

                console.log(this.state.dataToRender);

                if(counter === 10) 
                    clearInterval(interval);
                
             catch (e) 
                console.log(e.message);
            
        , 2000);
    

    renderList(item) 
        console.log(item);

        return (
            <ListItem
                roundAvatar
                title=item.name
                subtitle=item.des
            />
        );
    

    render() 
        return (
            <View style= flex: 1, alignItems: "stretch", backgroundColor: "skyblue" >
                <List>

                    <FlatList
                        data=this.state.dataToRender
                        renderItem=( item ) => this.renderList(item)
                        keyExtractor=item => item.id
                    />
                </List>
            </View>
        );
    

我只能获取我在构造函数中声明的第一个元素,但我在 serInterval 中附加的数据没有显示在页面上。

请帮我解决这个问题,或者如果有其他方法可以解决,请告诉我。

提前致谢。

【问题讨论】:

尽量不要使用concat而不是push来改变状态,或者使用扩展运算符将状态定义为let tempArray=...this.state.dataToRender; @PritishVaidya 我尝试使用dataToRender: tempArray.slice() 创建一个新数组,并且成功了。数组在代码中发生了变异。感谢您的帮助。 【参考方案1】:

您好,请尝试查看您可以在 FlatList 上使用的 extraData 参数:

通过将extraData=this.state 传递给 FlatList,我们确保 FlatList 本身会在 state.selected 更改时重新渲染。如果不设置此 prop,FlatList 将不知道它需要重新渲染任何项目,因为它也是一个 PureComponent,并且 prop 比较不会显示任何更改。

<FlatList
 ...
 extraData=this.state
/>

有关 FlatList 文档的更多信息:https://facebook.github.io/react-native/docs/flatlist.html

此外,您不应该需要来自 react 本机元素的 &lt;List&gt;,列表行为完全由您的 FlatList 处理。

【讨论】:

我在 FlatList 属性中添加了extraData=this.state.dataToRender。仍然列表没有更新。 @Shubham 应该是extraData=this.state,看看他们的文档。 你检查过代码吗?因为对我来说它不起作用。【参考方案2】:

就像说@AlexDG 平面列表是纯组件。要更新纯组件,请使用 key prop。

但不要过度,否则会导致不必要的重绘。

<FlatList
  key=this.state.dataToRender.length <---------- rerender
  data=this.state.dataToRender
  renderItem=( item ) => this.renderList(item)
  keyExtractor=item => item.id
/>

【讨论】:

问题是数组突变。永远不要在 react native 中改变数组或对象。【参考方案3】:

我自己有这个,碰巧读到了 OP 的 this comment:

问题是数组突变。永远不要在 react native 中改变数组或对象。

我确实这样改变了我的状态:

this.setState(prev =>
    prev.listData.push("stuff");
    return prev;
);

你也可以在问题中看到它:

let tempArray = this.state.dataToRender;
tempArray.push(temp);

改成之后

this.setState(prev => 
    let copy = Array.from(prev.listData);
    copy.push("stuff");
    return listData: copy;
);

但是,我的列表更新得很好!

因此,如果您在您的状态下对与列表的 data 相关的数组进行变异,您可能想看看这是否有帮助。

【讨论】:

以上是关于为啥 FlatList 在 React Native 中没有动态更新的主要内容,如果未能解决你的问题,请参考以下文章

react-native ScrollView 嵌套 FlatList滚动

React Native FlatList 嵌套在具有相同方向的 FlatList 中

在 React 中等效于来自 React Native 的 FlatList

在 React Native 中动态添加项目到 FlatList

React Native - FlatList - 内部状态

在 React Native 中使用 ScrollTo 的 FlatList