Iván
Iván

Reputation: 41

why does scroll doesnt work properly in chat app?

I've made a chat app in next react using firebase and tailwind. The idea is when the messages get to the bottom of the container that the scroll activates. Instead the messages keep going until they hit the bottom of the window and then the scroll activates. help.

const [messages, setMessages] = useState([]);
const scroll = document.getElementById("chatFeed");
if (scroll) {
  scroll.scrollTop = scroll.scrollHeight;
}

useEffect(() => {
  const q = query(collection(db, "messages"), orderBy("timestamp"));
  const unsubscribe = onSnapshot(q, (querySnapshot) => {
    let messages = [];
    querySnapshot.forEach((doc) => {
      messages.push({ ...doc.data(), id: doc.id });
    });
    setMessages(messages);
  });
  return () => unsubscribe();
}, []);

return (
  <>
    <div id="chatFeed" className="flex flex-col p-[10px] relative">
      {messages &&
        messages.map((message) => (
          <Message key={message.id} message={message} />
        ))}
    </div>
    {/* Send Message Compoenent */}
    <SendMessages scroll={scroll} />
    <span ref={scroll}></span>
  </>
);
};

Upvotes: 1

Views: 452

Answers (1)

Iv&#225;n
Iv&#225;n

Reputation: 41

So after a lot of tries i figure it out, youll need overflow in the chat container and you'll need to use useEffect for the event listener and sroll behavior and use ref in the chat container:

import { query, collection, orderBy, onSnapshot } from "firebase/firestore";
import { db } from "../firebase";
import React, { useState, useEffect, useRef } from "react";
import Message from "./Message";
import SendMessages from "./SendMessages";

const Chat = () => {
  const [messages, setMessages] = useState([]);
  const messageEl = useRef(null);

  useEffect(() => {
    if (messageEl) {
      messageEl.current.addEventListener("DOMNodeInserted", (event) => {
        const { currentTarget: target } = event;
        target.scroll({ top: target.scrollHeight, behavior: "smooth" });
      });
    }
  }, []);

  useEffect(() => {
    const q = query(collection(db, "messages"), orderBy("timestamp"));
    const unsubscribe = onSnapshot(q, (querySnapshot) => {
      let messages = [];
      querySnapshot.forEach((doc) => {
        messages.push({ ...doc.data(), id: doc.id });
      });
      setMessages(messages);
    });
    return () => unsubscribe();
  }, []);

  return (
    <>
      <div
        ref={messageEl}
        className="flex flex-col p-[10px] relative overflow-auto mb-[50px]"
      >
        {messages &&
          messages.map((message) => (
            <Message key={message.id} message={message} />
          ))}
      </div>
      {/* Send Message Compoenent */}
      <SendMessages />
    </>
  );
};

export default Chat;

Upvotes: 1

Related Questions