-1

I have a state named chats in which i am storing all messages from firebase and i'm trying to render it in app. but it does not render here is my component's state:

  const [chats, setChats] = useState([]);

I am bringing messages in UseEffect hook to get it on running of app

useEffect(() => {
    let merged_uid = uid_merger(current_user.id, chat_user.uid);
    database()
      .ref('/')
      .child(`chats/${merged_uid}`)
      .on('child_added', (msgs) => {
        console.log(msgs);
        chats.push(msgs.val());
        setChats(chats);
      });
  }, []);

but id does not render.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Aqsa Maan
  • 75
  • 1
  • 10

1 Answers1

2

since chats is a state you can't mutate it using chats.push(msgs.val()); instead what you need to do is to replace

chats.push(msgs.val());
setChats(chats);

with

setChats([...chats, msgs.val()])
laserany
  • 1,257
  • 1
  • 8
  • 17
  • it only renders last node.why is that? – Aqsa Maan Mar 28 '21 at 09:17
  • this is how i'm rendering `{chats.map((v, i) => { return ( {v.message} ); }) }` – Aqsa Maan Mar 28 '21 at 09:19
  • and if i do this `setChats([...chats, chats.push(msgs.val())]);` it all except last node. – Aqsa Maan Mar 28 '21 at 09:22
  • @AqsaMaan I'm not seeing anything wrong with your map function. I am not that familiar with fetching from firebase but it seems to me that you are only retrieving the data once in your useEffect. Maybe you need to have some sort of for loop there? – laserany Mar 28 '21 at 09:34
  • no i dont need loop. I only need to render on component mount. but i'm getting nothing in last node – Aqsa Maan Mar 28 '21 at 09:39
  • In that case I recommend that you debug by console log both the chats state and message and see what you get in return. – laserany Mar 28 '21 at 09:50
  • I have checked it. in chats, i am getting all messages but it does not render last one. I mean it does render last one but messenge shoes empty. – Aqsa Maan Mar 28 '21 at 09:56
  • like this:https://drive.google.com/file/d/1L1XbUpQu5JAWQ0ImOSadof8i9D0-qjeu/view?usp=sharing – Aqsa Maan Mar 28 '21 at 09:59
  • @AqsaMaan Thank you for sending an example of the screenshot to clarify. Can you send another screen shot with higher values? like 10 messages? – laserany Mar 28 '21 at 10:04
  • I'm wonder if this is because it is being rendered on some sort of emulator. If this is on a browser then it should've rendered all messages for sure. – laserany Mar 28 '21 at 10:04
  • https://drive.google.com/file/d/1eozDc0Ltff7wghtc-v7FfA7HtW16dWZH/view?usp=sharing – Aqsa Maan Mar 28 '21 at 11:05
  • Thanks Aqsa. I'm pretty sure that this is not a react issue. It could be something that has to do with your styling. Can you please paste what you use for styling the component? for example I'm noticing that the first and last element are styled differently – laserany Mar 28 '21 at 12:38
  • its not first and last. its more like sender and receiver but last message always show like yellow which is of sender even if last msg is not of sender – Aqsa Maan Mar 28 '21 at 12:54
  • here is code :https://drive.google.com/file/d/1Qj2Ta0lVzAitIrXP78Qa5jowG01lRPBT/view?usp=sharing – Aqsa Maan Mar 28 '21 at 12:56
  • @AqsaMaan please replace setChats([...chats, chats.push(msgs.val())]) with setChats([...chats, msgs.val()]) – laserany Mar 28 '21 at 13:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/230479/discussion-between-aqsa-maan-and-laserany). – Aqsa Maan Mar 28 '21 at 15:32