1

I want to scroll to the bottom of the div whenever a new message is sent in the Message. I can do this with jQuery but wondering what the best approach in React is.

This is the Messages.js component I am in. Thank you in advance!

const Messages = (props) => {

    const [inputMessage, setInputMessage] = useState('');

    const handleChange = (event) => {
    setInputMessage(event.target.value);
  }

  const handleSubmit = (event, message) => {
    event.preventDefault();
    props.setRoomMessages([...props.roomMessages, {id: Date.now(), name: props.username, message: inputMessage}]);
    setInputMessage('');
  }
  
    const messages = props.roomMessages.map((message, index) => {
        return (
            <Message 
                key={index}
                name={message?.name}
                message={message?.message}
            />
        )
    })

    return (
        <>
            <div className="Messages">
                {messages}
            </div>
        
            <form className="chat-input form-inline" onSubmit={handleSubmit}>
        <div className="form-group">
                <input 
                    className="form-control"
                    type="text" 
                    value={inputMessage}
                    placeholder="Type a message..."
                    onChange={handleChange}
                />‍
          <button className="btn btn-link">Send</button>
        </div>
      </form>
        
    </>
    )
}

export default Messages;

Ken Ryan
  • 539
  • 1
  • 10
  • 31
  • There are ways to integrate jQuery in React (though you should avoid doing so if you can). You can implement the same functionality using vanilla javascript. Check the example on this question: https://stackoverflow.com/questions/270612/scroll-to-bottom-of-div – shubhendu madhukar Apr 30 '21 at 03:11

1 Answers1

0

Try this, one way to do it is to use ref

import { useState, useRef } from 'react';

const Messages = props => {
    const [inputMessage, setInputMessage] = useState('');
    const myMessage = useRef(null);

    const handleChange = event => {
        setInputMessage(event.target.value);
    };

    const handleSubmit = (event, message) => {
        event.preventDefault();

        props.setRoomMessages([...props.roomMessages, { id: Date.now(), name: props.username, message: inputMessage }]);
        setInputMessage('');

        // HERE IS THE NEW CODE
        if (myMessage && myMessage.current) {
            myMessage.current.scrollTop = myMessage.current.scrollHeight;
        }
    };

    const messages = props.roomMessages.map((message, index) => {
        return <Message key={index} name={message?.name} message={message?.message} />;
    });

    return (
        <>
            <div className="Messages" ref={myMessage}>
                {messages}
            </div>

            <form className="chat-input form-inline" onSubmit={handleSubmit}>
                <div className="form-group">
                    <input
                        className="form-control"
                        type="text"
                        value={inputMessage}
                        placeholder="Type a message..."
                        onChange={handleChange}
                    />
                    ‍<button className="btn btn-link">Send</button>
                </div>
            </form>
        </>
    );
};

export default Messages;
DevBF
  • 247
  • 4
  • 15
  • That worked! thank you so much. Could you explain the .current ? or point me towards some article? Thank you!!! – Ken Ryan Apr 30 '21 at 18:30
  • No worries, the article of ref in react that i linked above should explain everything. I recommend you reading it thoroughly. Otherwise [here's](https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs) the specific section that explains it @KenRyan – DevBF May 02 '21 at 23:23