【问题标题】:React Native FlatList component data constantly refreshing after firebase data call without consistent display of Firebase dataReact Native FlatList组件数据在firebase数据调用后不断刷新,Firebase数据没有一致显示
【发布时间】:2020-05-21 11:13:27
【问题描述】:

我正在尝试在本机反应中构建一个平面列表,其中显示帖子及其信息和用户信息。所有这些数据都存储在 firebase 中。我使用以下函数将此数据调用到数据状态变量中:

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));
    });
  };

这个函数将正确的数据加载到数据状态中,但是在我尝试将这些数据加载到 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>

我在以下代码中调用 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();
    });
  };

此数据在我重新加载后会闪烁,但不会始终显示在屏幕上。当我不重新加载时,屏幕上不会出现任何内容。我的状态如下所示:

constructor(props) {
    super(props);

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

我的总体问题是:如何使平面列表中的数据始终保持在屏幕上,而不总是重新加载和刷新数据?任何帮助将不胜感激。提前谢谢!

【问题讨论】:

  • 您何时何地致电getPosts
  • 我刚刚更新了问题以包含此代码。很抱歉有歧义。

标签: javascript reactjs firebase react-native google-cloud-firestore


【解决方案1】:

根据我的经验,如果您将 setTimeout 放入由 onEndReached 调用的函数中,FlatList 的性能会更好。我经历过 FlatLists 不断刷新,因为在再次调用 onEndReached 之前它还没有完成加载更多数据。 FlatList 应该有内置的东西来防止这成为一个问题,但它并不总是有效。

在FlatList 中使用bounces={false} 也可以帮助解决这个问题,因为有时反弹会导致在FlatList 完成更新之前连续触发两次onEndReached。

这是我在我的一个应用中用于 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();
  }

}

我不确定您的显示问题是否是由同一原因引起的。如果在修复了持续刷新后仍然存在问题,请尝试检查它是否在 IOS 和 Android 中都有问题,或者只是其中一个问题。

我记得曾经在 Android 上遇到过类似的问题。我通过玩弄一些与 FlatList 冲突的样式选择来修复它,但我不记得它们到底是什么。如果只是 FlatList 是空白的,它们可能与隐藏溢出有关。

如果整个屏幕(包括 FlatList 之外的所有其他组件)也变为空白,我认为您可能需要使用 flex:1 将整个屏幕包裹起来。

【讨论】:

  • 感谢您的回复!我仍然遇到一个问题,即仅在我重新加载屏幕后才显示数据,并且在我这样做之前数据不会立即显示。你会碰巧知道如何解决这个问题吗?再次感谢您!
  • 我不确定,但您使用的是 react-navigation 吗?如果是这样,所有页面都必须包含在 flex 1 中,以避免第二次呈现空白页面,这是由于在给定信息时页面会改变大小的反应导航问题。如果您不使用 react-navigation,我不知道是什么原因造成的,但我的猜测可能是某些依赖项与屏幕更改相冲突,类似于 react 导航的方式,或者是在数据更改后阻止自动重新渲染,例如this.state.data 被排除在外的 shouldComponentUpdate 函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 2019-03-25
  • 2021-06-26
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多