简体   繁体   English

React Native FlatList 组件数据在 firebase 数据调用后不断刷新,Firebase 数据显示不一致

[英]React Native FlatList component data constantly refreshing after firebase data call without consistent display of Firebase data

I am trying to build a flatlist in react native where posts are displayed with their information and the information of their user.我正在尝试在 React Native 中构建一个平面列表,其中显示帖子及其用户信息。 All of this data is stored in firebase.所有这些数据都存储在 firebase 中。 I am calling this data into a data state variable with the following function:我使用以下函数将此数据调用到数据状态变量中:

getPosts = (limit = 20) => {
    var list = [];
    firebase.firestore()
      .collection("posts").get().then((querySnapshot) => {
        querySnapshot.forEach(async (doc) => {
          var tempList = doc.data();
          const usersQs = await firebase.firestore().collection("users").where('email', '==', doc.data().email).get();
          usersQs.forEach(doc2 => {
            Object.assign(tempList, {
              "userName": doc2.data().name,
              "avatar": doc2.data().avatar
            });
          });

          list.push(tempList);
        });
        list.sort(function(a, b) {
          var c = b.timestamp;
          var d = a.timestamp;
          return c - d;
        });
        this.setState({
          data: list,
          fullData: list
        });
      });

    return new Promise((resolve, reject) => {
      this.func;
      resolve(_.take(this.state.fullData, limit));
    });
  };

This function loads the correct data into the data state, but after I try to load this data into the Flatlist, which looks like this:这个函数将正确的数据加载到数据状态中,但是在我尝试将这些数据加载到 Flatlist 之后,它看起来像这样:

renderPost = post => {
    return (
      <View style={styles.feedItem}>
        <Image source={post.avatar} style={styles.avatar} />
        <View style={{ flex: 1 }}>
          <View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
            <View>
              <Text style={styles.name}>{post.userName}</Text>
              <Text style={styles.timestamp}>{moment(post.timestamp).fromNow()}</Text>
            </View>

            <Ionicons name="ios-more" size={24} color="#73788B" />
          </View>

          <Text style={styles.post}>{post.text}</Text>

          <Image source={post.image && {uri: post.image}} style={styles.postImage} resizeMode="cover" />

          <View style={{ flexDirection: "row" }}>
            <Ionicons name="ios-heart-empty" size={24} color="#73788B" style={{ marginRight: 16 }} />
            <Ionicons name="ios-chatboxes" size={24} color="#73788B" />
          </View>
        </View>
      </View>
    );
  };

  render() {
    return (
      <View style={styles.container}>
        <View style={styles.header}>
          <Text style={styles.headerTitle}>Feed</Text>
        </View>

        <FlatList
          style={styles.feed}
          data={this.state.data}
          renderItem={({ item }) => this.renderPost(item)}
          keyExtractor={item => item.timestamp.toString()}
          showsVerticalScrollIndicator={false}
          ListFooterComponent={this.renderFooter}
          refreshing={this.state.refreshing}
          onRefresh={this.handleRefresh}
          onEndReached={this.handleLoadMore}
          onEndThreshold={100}
        />
      </View>

I call the getPosts function in the following code, which runs on reload and refresh:我在以下代码中调用 getPosts 函数,该函数在重新加载和刷新时运行:

  componentDidMount() {
    this.makeRemoteRequest();
  }
...
  makeRemoteRequest = _.debounce(() => {
    this.setState({ loading: true });

    this.getPosts(this.state.postNumLoad)
      .then(posts => {
        this.setState({
          loading: false,
          data: posts,
          fullData: posts,
          refreshing: false
        });
      })
      .catch(error => {
        this.setState({ error, loading: false, refreshing: false });
      });
  }, 250);

  handleRefresh = () => {
    this.setState({
      refreshing: true
    }, () => {
      this.makeRemoteRequest();
    });
  };

  handleLoadMore = () => {
    this.setState({
      postNumLoad: this.state.postNumLoad + 20
    }, () => {
      this.makeRemoteRequest();
    });
  };

This data flashes after I reload it, but it does not stay on the screen consistently.重新加载后,此数据会闪烁,但不会始终显示在屏幕上。 When I don't reload, nothing appears on the screen.当我不重新加载时,屏幕上不显示任何内容。 My state looks like the following:我的状态如下所示:

constructor(props) {
    super(props);

    this.state = {
      data: [],
      downloadImage: '../assets/images/temporaryProfilePicture.jpg',
      loading: false,
      error: null,
      fullData: [],
      refreshing: false,
      postNumLoad: 20
    };
  }

My question overall is: How would I make the data in the flatlist stay constantly on the screen without always reloading and flashing the data?我的总体问题是:如何使 flatlist 中的数据始终保持在屏幕上,而无需始终重新加载和闪烁数据? Any help would be largely appreciated.任何帮助将不胜感激。 Thank you in advance!先感谢您!

In my experience, FlatList performs better if you put a setTimeout in the function that's called by onEndReached.根据我的经验,如果将 setTimeout 放在 onEndReached 调用的函数中,FlatList 的性能会更好。 I have experienced FlatLists constantly refreshing because it hasn't finished loading more data before onEndReached gets called again.我经历过 FlatLists 不断刷新,因为它在 onEndReached 再次被调用之前还没有完成加载更多数据。 FlatList is supposed to have something built in that prevents this being an issue, but it doesn't always work. FlatList 应该有一些内置的东西可以防止这是一个问题,但它并不总是有效。

Using bounces={false} in FlatList can also help with this, since sometimes a bounce will cause onEndReached to be triggered twice in a row before the FlatList has finished updating.在FlatList 中使用bounces={false} 也可以帮助解决这个问题,因为有时在FlatList 完成更新之前,弹跳会导致onEndReached 连续触发两次。

Here's an example of a set of functions I use for onEndReached in one of my apps:这是我在我的一个应用程序中用于 onEndReached 的一组函数的示例:

gettingData(){

   this.setState({refreshing: true, showFooter: true});

       this.GetMyData().then(() => {
       this.setState({refreshing: false, showFooter: false, loading: false});
   });

     }


 waitingForData(){

   setTimeout(() => {
     if(this.state.showFooter === false && this.state.listData.length > 0){
       //console.log('getting after waiting');
       this.gettingData();
     }else{
       //console.log('waiting again');
       this.waitingForData();
     }
   }, 15000)

 }

_onEndList = () => {

  if(this.state.showFooter === false && this.state.listData.length > 0){
    //console.log('getting');
    this.gettingData();


  }else{
//console.log('waiting');
    this.waitingForData();
  }

}

I'm not sure if your display issue is caused by the same thing or not.我不确定您的显示问题是否是由同一件事引起的。 If that's still a problem after the constant refreshing is fixed try checking if it's a problem in both IOS and Android, or just one or the other.如果在固定刷新后仍然存在问题,请尝试检查是 IOS 和 Android 都存在问题,还是仅存在其中一个问题。

I remember having an issue like that once on Android only.我记得只有一次在 Android 上遇到过这样的问题。 I fixed it by playing around with some styling choices that were conflicting with FlatList but I don't remember what exactly those were.我通过尝试一些与 FlatList 冲突的样式选择来修复它,但我不记得那些到底是什么。 They may have had to do with keeping overflow hidden if it's just the FlatList that's blank.如果它只是空白的 FlatList,它们可能与保持溢出隐藏有关。

If the whole screen including all other components outside of FlatList also go blank, I think it may be that you need to wrap the whole screen in something with flex:1.如果整个屏幕包括 FlatList 之外的所有其他组件也变成空白,我认为您可能需要用 flex:1 将整个屏幕包裹起来。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM