skip to Main Content

Auto-scroll to bottom in react:
I have a chatbot that have conversations with people, I need it to scroll to the bottom automatically when it generates new answers.

I am not familiar with React and I am using a prepared code so I’m not sure how to implement the auto scroll.
I tried some ways but it didn’t work out.

here is my code:


function App() {
  const [messages, setMessages] = useState([
    {
      message: "Hello there! I'm your Health Assistant, designed to make your wait more comfortable and informative. Whether you have questions about your health, need general information, or just want a friendly chat, I'm here for you. Feel free to ask me anything, and let's make your time in the waiting room as pleasant as possible!",
      sentTime: "just now",
      sender: "ChatGPT"
    }
  ]);




  const [isTyping, setIsTyping] = useState(false);
  
  const handleSend = async (message) => {

  const newMessage = {
      message,
      direction: 'outgoing',
      sender: "user"
    };

  const newMessages = [...messages, newMessage];
    
    setMessages(newMessages);

    // Initial system message to determine ChatGPT functionality
    // How it responds, how it talks, etc.
    setIsTyping(true);
    await processMessageToChatGPT(newMessages);
  };

  async function processMessageToChatGPT(chatMessages) { // messages is an array of messages
    // Format messages for chatGPT API
    // API is expecting objects in format of { role: "user" or "assistant", "content": "message here"}
    // So we need to reformat

    let apiMessages = chatMessages.map((messageObject) => {
      let role = "";
      if (messageObject.sender === "ChatGPT") {
        role = "assistant";
      } else {
        role = "user";
      }
      return { role: role, content: messageObject.message}
    });


    // Get the request body set up with the model we plan to use
    // and the messages which we formatted above. We add a system message in the front to'
    // determine how we want chatGPT to act. 
    const apiRequestBody = {
      "model": "gpt-4",
      "messages": [
        systemMessage,  // The system message DEFINES the logic of our chatGPT
        ...apiMessages // The messages from our chat with ChatGPT
      ]
    }

    await fetch("https://api.openai.com/v1/chat/completions", 
    {
      method: "POST",
      headers: {
        "Authorization": "Bearer " + API_KEY,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(apiRequestBody)
    }).then((data) => {
      return data.json();
    }).then((data) => {
      console.log(data);
      setMessages([...chatMessages, {
        message: data.choices[0].message.content,
        sender: "ChatGPT"
      }]);
      setIsTyping(false);
    });
  }

  return (
    <div className="App">
      <div style={{ position:"relative", height: "550px", width: "900px"  }}>
        <MainContainer>

          <ChatContainer>       
            <MessageList 
              scrollBehavior="smooth" 
              typingIndicator={isTyping ? <TypingIndicator content="Chatbot is typing" /> : null}
            >
              {messages.map((message, i) => {
                console.log(message)
                return <Message key={i} model={message} />
              })}
            </MessageList>
            <MessageInput placeholder="Type message here" onSend={handleSend} attachButton={false} />        
          </ChatContainer>
        </MainContainer>

      </div>
    </div>
  )
}

export default App

2

Answers


  1. Chosen as BEST ANSWER

    thanks for your answer. can you tell me where should I put this line of code?

    enter code here.   useEffect(() => {
    

    messageListRef.current.scrollTo(0, messageListRef.current.scrollHeight); }, [messages]);


  2. Create a ref for the MessageList:

    const messageListRef = useRef(null);
    

    Add the ref to the MessageList element:

    <MessageList
      ref={messageListRef}
      scrollBehavior="smooth"
      typingIndicator={isTyping ? <TypingIndicator content="Chatbot is typing" /> : null}
    >
      {/* ... */}
    </MessageList>
    

    Scroll to the bottom after adding new messages:

    useEffect(() => {
      messageListRef.current.scrollTo(0, messageListRef.current.scrollHeight);
    }, [messages]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search