decheftw
decheftw

Reputation: 61

Firebase ref.on('value') continuously calls, even when there is no change

I am using an event listener to check for changes to my realtime database.

  const [chats, setChats] = useState({});
  const ref = db.ref(`users/${sender}/chat/`);
  ref.on('value', (snapshot) => {
    const data = snapshot.val();
    setChats(data);
  });

I keep getting too many re-renders. The Firebase docs say that it's only supposed to update when there's a change to the children. Did I do something wrong? Is there a workaround?

Upvotes: 0

Views: 719

Answers (1)

Phil
Phil

Reputation: 164736

The issue is most likely that the code in your question runs for each render, changes the state and thus, re-renders. Ala infinite loop

Try using a useEffect hook. Bonus points for removing the listener in the cleanup

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

useEffect(() => {
  const ref = db.ref(`users/${sender}/chat/`);

  // value listener function
  const onValue = (snapshot) => {
    setChats(snapshot.val());
  };

  // register listener
  ref.on("value", onValue);

  // return a cleanup function to remove the listener
  return () => ref.off("value", onValue);
}, [sender]);

Using the V9 SDK looks a little different. The onValue() listener returns its own unsubscribe function

useEffect(() => {
  const chatRef = ref(db, `users/${sender}/chat/`);

  // return the unsubscribe function
  return onValue(chatRef, (snapshot) => {
    setChats(snapshot.val());
  });
}, [sender]);

Upvotes: 2

Related Questions