首页 > 解决方案 > 如何从 React Native FlatList 中的异步函数返回值?

问题描述

**我正在尝试过滤来自被阻止用户的帖子。**

我做了一个异步函数来检查用户是否被阻止:

checkBlocked = async userId => {
  try {
  let snapshot = await firebase.database().ref('Blocked/' + firebase.auth().currentUser.uid).orderByChild('uid').equalTo(userId).once('value')
    return snapshot.exists();
  }
  catch(error) {
    return false;
  }
}

我想返回 flatlist 中的值,以便相应地显示帖子:-

<FlatList
        inverted
        extraData={this.state.blocked}
        data={this.state.arrData}
        keyExtractor={item => item.key}

        renderItem={({ item }) => {
         
         
          this.checkBlocked(item.id).then(val => this.setState({blocked: val}));
         
            if(this.state.blocked == true){
              return (
              //something
                 )
            }

          else {
             
          return (
            //something
                 )
            }
         }}

上述方法不起作用,我哪里出错了?

标签: javascriptreactjsfirebasereact-nativereact-native-flatlist

解决方案


我们没有确切的所有细节,但我可以看到这里的逻辑流程很奇怪。让我们看看发生了什么

  1. FlatList呈现与this.state.arrData
  2. 在 的每次迭代中renderItemcheckBlocked使用用户的 id 进行异步调用
  3. 你渲染的东西基于this.state.blocked
  4. 你的checkBlocked承诺解决了,blocked状态中的变量被返回值覆盖

您正在做出一个承诺 ( checkBlocked(id).then()),但您render不会等待该承诺在它返回之前解决。因此,您this.state.blocked尚未将您的定义定义为您在退货声明中的想法。 此外setStateasync,这意味着您不能依赖return语句中的值作为您刚刚设置的值checkBlocked

更好的模式是在渲染组件之前,通过异步循环运行用户列表,其中每个条目都使用checkBlocked. 然后,您可以构造一个对象数组,例如usersWithBlockedStatus,每个对象都有一个用户名和阻止状态。然后过滤掉所有blocked状态为 true 的条目,并调用它usersThatAreNotBlocked。仅当所有这些都完成后,您才能FlatList将数据呈现为usersThatAreNotBlocked.

您可以在问题How to call fetch() inside renderItem on FlatList?中找到另一个写得很好的解释?


推荐阅读