从firestore动态获取数据时RenderItem不渲染[重复]

Posted

技术标签:

【中文标题】从firestore动态获取数据时RenderItem不渲染[重复]【英文标题】:RenderItem not rendering when dynamically getting data from firestore [duplicate] 【发布时间】:2021-09-09 02:34:47 【问题描述】:

ChatsOverview 屏幕包含一个呈现 ChatItems 的 FlatList。 FlatList 的 data 属性是一个聊天 ID 数组。这些 id 将在 firestore 查询中使用,以获取包含 ChatItem 所需数据的文档。

我的问题是 ChatItem 没有从 firestore 查询中获取返回的数据,而当我从 get() 记录返回数据时,我得到了我需要的数据。

我已经尝试创建一个单独的函数来呈现 ChatItem 并且该函数是异步的,尝试等待 firestore 返回数据但无济于事..

每次将用户添加到聊天中时,FlatList 都应该重新呈现(chatIds,即 chatIdsListener)。

我在代码中做了一些注释,以显示它的打印位置/数据按预期显示。

ChatsOverviewScreen:

const ChatsOverviewScreen = ( navigation ) => 
  const currentUid = firebase.auth().currentUser.uid;

  const [chatIds, setChatIds] = useState([]);

  useEffect(() => 
    const chatIdsListener = firebase
      .firestore()
      .collection('users')
      .doc(currentUid)
      .onSnapshot(querySnapshot => 
        setChatIds(querySnapshot.data().chats);
      );

    return () => chatIdsListener();
  , []);

  const renderChatItem = async chatId => 
    const querySnapshot = await firebase
      .firestore()
      .collection('chats')
      .where('chatId', '==', chatId)
      .get();

    querySnapshot.forEach(doc => 
      if (doc.id === chatId) 
        console.log('rendering chatItem', doc.data());

        return (
          <ChatItem
            key=chatId
            chatData=doc.data()
            currentUid=currentUid
          />
        );
      
    );
  ;

  return (
    <SafeAreaView style=styles.parentContainer>
      <Layout style=styles.chatsContainer>
        chatIds.length > 0 ? (
          <FlatList
            data=chatIds
            renderItem=( item ) => 
              firebase
                .firestore()
                .collection('chats')
                .where('chatId', '==', chatId)
                .get()
                .then(querySnapshot => 
                  querySnapshot.forEach(doc => 
                    if (doc.id === item) 
                      console.log('rendering chatItem', doc.data()); // logs here

                      return (
                        <ChatItem // nothing being logged here for 'chatData'
                          key=item
                          chatData=doc.data()
                          currentUid=currentUid
                        />
                      );
                    
                  );
                );
              // renderChatItem(item);
            
            keyExtractor=item => item
            extraData=chatIds
          />
        ) : (
          <Layout style=styles.emptyContainer>
            <Text style=styles.emptyText>
              `Sorry, we can't find any chats.\nHead to the Team Up screen to get started!`
            </Text>
          </Layout>
        )
      </Layout>
    </SafeAreaView>
  );
;

聊天项目:

const ChatItem = ( chatData, currentUid, onPress ) => 
  const  name, imagePath  = chatData.participants.filter(
    user => user.id !== currentUid
  )[0];

  console.log(name, imagePath); // not printing anything

  let message = '',
    timestamp = '',
    id = '';

  if (chatData.latestMessage !== undefined) 
    message = chatData.latestMessage.message;
    timestamp = chatData.latestMessage.timestamp;
    id = chatData.latestMessage.id;
  

  return (
    <Pressable style=styles.cardContainer onPress=() => onPress()>
      <Layout style=styles.avatarContainer>
        imagePath.length > 0 ? (
          <Image source= uri: imagePath  style=styles.avatar />
        ) : (
          <UserAvatar name=name size=50 fontSize=22 />
        )
      </Layout>
      <Layout style=styles.detailsContainer>
        <Layout style=styles.topChatContainer>
          <Layout style=styles.nameContainer>
            <Text category='h6' style=styles.name>
              name
            </Text>
          </Layout>
          <Layout style=styles.timeContainer>
            timestamp.length > 0 && (
              <Text>dayjs(timestamp).format('h:mm A')</Text>
            )
          </Layout>
        </Layout>
        <Layout style=styles.bottomChatContainer>
          message.length > 0 ? (
            <Text numberOfLines=1>
              currentUid === id ? `You: $message` : message
            </Text>
          ) : (
            <Text>Click on here to start a conversation!</Text>
          )
        </Layout>
      </Layout>
    </Pressable>
  );
;

感谢您的任何意见,谢谢

【问题讨论】:

【参考方案1】:

如果我没记错的话,renderItem 属性只是用于渲染 UI。在那里有异步任务不是一个好主意。我建议过滤钩子中的数据,然后将过滤后的数据传递给renderItem

【讨论】:

感谢您的意见!是的,我已经尝试了您的建议,但我正在努力解决如何正确获取 redux 商店中的最新状态。昨天我问了一个问题,当时 ChatsOverviewScreen 的代码更长,在卡住了 12 多个小时后,我决定今天重做同一个屏幕。如果你可以请看这个,***.com/questions/68119939/…

以上是关于从firestore动态获取数据时RenderItem不渲染[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Firestore:仅当有更新时才从服务器获取数据,否则从缓存中获取

从 StreamBuilder BloC firestore Flutter 获取数据时出错

Firestore 规则 - 动态路径

Flutter web无法从firestore获取数据

从 Firestore 获取数据并将其映射到提供程序对象

即使从缓存中获取数据,Firestore 数据库读取计数也会增加