title: Performing firestore query in renderItem of FlatList to pass data to return Child
body: <p>this is a school project and I have been stuck on a bug for more than 12 hours...</p>
  <p>The context is user accepts a chat request from the sender and upon doing so, a new chat 'room' is created and shown when i go back to the <strong>Chats</strong> tab. All these are done in a <code>TabNavigator</code>.</p>
  <p>My expected result is to dynamically/automatically load the <strong>ChatItem</strong> in the <strong>Chats</strong> tab (i.e. these ChatItems live in a <code>FlatList</code>) when I as a user accepts the incoming chat requests.</p>
  <p>The problem is that I am trying to get the sender's data from <code>firestore</code> but I keep getting undefined for its data. My initial load for the app gets all users data from <code>firestore</code> and loads up the Redux store.</p>
  <p>Flow:
  Sender sends chat request -&gt; Updates <code>firestore</code> and the changes are being listened to -&gt; Receiver sees a new chat request (this works) -&gt; Accepts -&gt; New chat 'room' created for sender and receiver (should show automatically)</p>
  <p>Ways I have tried to not get an undefined sender:</p>
  <ol>
  <li>Accepting a chat request, updates <code>firestore</code> and then Redux store. Retrieve all users data from 'supposedly' updated Redux store. But it's undefined</li>
  <li>Wrote a listener to listen for changes in the <code>users</code> collection in <code>firestore</code> but it's 1 step slower when rendering the items in the FlatList and I get undefined sender's data</li>
  <li>Wrote conditional checks to check if sender's data is undefined, if yes, perform a DIRECT <code>firestore</code> query to get the sender's data from the <code>users</code> collection. But still I get undefined.</li>
  </ol>
  <p>I suspect all these is due to the FlatList re-rendering again but I'm not exactly sure how to control it.</p>
  <p>I did specify a state for the prop <code>extraData</code> in the <code>FlatList</code>.</p>
  <p>I have exhausted all ways possible, did all research, and I'm dead flat exhausted.</p>
  <p>I appreciate any help please, thank you so much.</p>
  <p>Here is the <code>ChatsOverviewScreen</code>, cleaned up unnecessary codes:</p>
  <pre class="lang-js prettyprint-override"><code>const ChatsOverviewScreen = ({ navigation }) =&gt; {
    const currentUid = firebase.auth().currentUser.uid;
  
    const userData = useSelector(state =&gt; state.user.userData);
    // const usersData = useSelector(state =&gt; state.users.usersData);
    const [initial, setInitial] = useState(true);
    const [chats, setChats] = useState([]);
    const [chatsLatestMsg, setChatsLatestMsg] = useState([]);
    const [usersData, setUsersData] = useState([]);
  
    // To listen for any update in Users collection
    // and then update usersData state
    useEffect(() =&gt; {
      const usersDataListener = firebase
        .firestore()
        .collection('users')
        .onSnapshot(querySnapshot =&gt; {
          let data = [];
  
          querySnapshot.forEach(doc =&gt; {
            if (doc.id !== currentUid) {
              data.push({ id: doc.id, ...doc.data() });
            }
          });
  
          setUsersData(data);
        });
  
      return () =&gt; usersDataListener();
    }, []);
  
    // To listen for any chat created for current user
    useEffect(() =&gt; {
      const chatsListener = firebase
        .firestore()
        .collection('users')
        .doc(firebase.auth().currentUser.uid)
        .onSnapshot(querySnapshot =&gt; {
          const latestChats = querySnapshot.data().chats;
          setChats(latestChats);
        });
  
      return () =&gt; chatsListener();
    }, []);
  
    // useEffect(() =&gt; {
    //   getUsers();
    // }, [chats]);
  
    // const getUsers = async () =&gt; {
    //   const querySnapshot = await firebase.firestore().collection('users').get();
  
    //   let temp_users = [];
  
    //   querySnapshot.forEach(doc =&gt; {
    //     if (currentUid !== doc.id) {
    //       temp_users.push({ id: doc.id, ...doc.data() });
    //     }
    //   });
  
    //   setUsersData(temp_users);
    // };
  
    return (
      &lt;SafeAreaView style={styles.parentContainer}&gt;
        &lt;FlatList
          data={chats}
          renderItem={({ item }) =&gt; {
            let peer;
            peer = usersData.filter(data =&gt; data.chats.includes(item))[0];
            let latestChat =
              chatsLatestMsg.length &gt; 0
                ? chatsLatestMsg.filter(data =&gt; data.chatId === item)[0]
                : {};
  
            // console.log('before condition', peer);
  
            // if (peer === undefined) {
            // firebase
            //   .firestore()
            //   .collection('users')
            //   .where('chats', 'array-contains', item)
            //   .get()
            //   .then(querySnapshot =&gt; {
            //     let data = [];
  
            //     querySnapshot.forEach(doc =&gt; {
            //       if (doc.id !== currentUid) {
            //         data.push({ id: doc.id, ...doc.data() });
            //       }
            //     });
  
            //     peer = data.filter(user =&gt; user.chats.includes(item))[0];
  
            //     console.log('undefined', peer);
  
            //     return (
            //       &lt;ChatItem
            //         key={item}
            //         currentUid={userData.id}
            //         latestChat={latestChat}
            //         chatId={item}
            //         peer={peer}
            //         onPress={navigateChat}
            //       /&gt;
            //     );
            //   });
            // }
  
            console.log('!undefined', peer);
  
            return (
              &lt;ChatItem
                key={item}
                currentUid={userData.id}
                latestChat={latestChat}
                chatId={item}
                peer={peer} // I keep getting undefined peer right here!
                onPress={navigateChat}
              /&gt;
            );
          }}
          keyExtractor={item =&gt; item}
          extraData={chats}
        /&gt;
      &lt;/SafeAreaView&gt;
    );
  };
  </code></pre>
  <p>And finally, the <code>ChatItem</code>:</p>
  <pre class="lang-js prettyprint-override"><code>const ChatItem = ({ peer, currentUid, chatId, onPress, latestChat }) =&gt; {
    let message = '',
      timestamp = '',
      id = '';
  
    if (latestChat.latestMessage !== undefined) {
      message = latestChat.latestMessage.message;
      timestamp = latestChat.latestMessage.timestamp;
      id = latestChat.latestMessage.id;
    }
  
    return (
      &lt;Pressable
        style={styles.cardContainer}
        onPress={() =&gt;
          onPress({
            peerData: peer,
            chatId: chatId,
            id: peer.id,
            name: peer.name,
            imagePath: peer.imagePath
          })
        }
      &gt;
        &lt;Layout style={styles.avatarContainer}&gt;
          {peer.imagePath.length &gt; 0 ? (
            &lt;Image source={{ uri: peer.imagePath }} style={styles.avatar} /&gt;
          ) : (
            &lt;UserAvatar name={peer.name} size={50} fontSize={22} /&gt;
          )}
        &lt;/Layout&gt;
        &lt;Layout style={styles.detailsContainer}&gt;
          &lt;Layout style={styles.topChatContainer}&gt;
            &lt;Layout style={styles.nameContainer}&gt;
              &lt;Text category='h6' style={styles.name}&gt;
                {peer.name}
              &lt;/Text&gt;
            &lt;/Layout&gt;
            &lt;Layout style={styles.timeContainer}&gt;
              {timestamp.length &gt; 0 &amp;&amp; (
                &lt;Text&gt;{dayjs(timestamp).format('h:mm A')}&lt;/Text&gt;
              )}
            &lt;/Layout&gt;
          &lt;/Layout&gt;
          &lt;Layout style={styles.bottomChatContainer}&gt;
            {message.length &gt; 0 ? (
              &lt;Text numberOfLines={1}&gt;
                {currentUid === id ? `You: ${message}` : message}
              &lt;/Text&gt;
            ) : (
              &lt;Text&gt;Click on here to start a conversation!&lt;/Text&gt;
            )}
          &lt;/Layout&gt;
        &lt;/Layout&gt;
      &lt;/Pressable&gt;
    );
  };
  </code></pre>