Nick
Nick

Reputation: 189

How to make the scrollbar always stick to the bottom when new data is added

I have a scrollable content and we could see our scrollbar appear when we keep inserting new data. I want to position the scrollbar always at the bottom in order to avoid scrolling manually. If you take Messenger for an example, when you type a message and submit it, our scroll height increases, but the scroll doesn't move up and down.

I tried to do the same using the following technique:

const App = () => {
    const myRef = useRef<HTMLDivElement>(null)

    const [msgs, setMsgs] = useState<string[]>([])
    const [text, setText] = useState<string>("")

    const scrollToMyRef = () => {
        if (myRef.current) {
            myRef.current.scrollTop = myRef.current.scrollHeight
        }
    };

    const handleInput = (e: React.KeyboardEvent<HTMLInputElement>) => {
        if (e.key === 'Enter') {
            // setText('')
            setMsgs(prevState => [...prevState, text])
        }
    }

    useEffect(() => {
        scrollToMyRef()
    }, [msgs])

    return (
        <div className="app">
            <div className="container" ref={myRef}>
                <div className={"messages-list"}>
                    {
                        msgs.map((msg, i) => (
                            <div key={i}>{msg}</div>
                        ))
                    }
                </div>
                <div className="form">
                    <input
                        type={"text"}
                        onKeyPress={e => handleInput(e)}
                        value={text}
                        onChange={(e) => setText(e.target.value)}
                    />
                    <input type={"button"} value={"add"} />
                </div>
            </div>
        </div>
    );
} 

The problem is that our scroll moves up and down, causing the content to "blink/flicker". Why exactly does this happen?

I have also tried scrollIntoView but it does not provide the desired output as well.

Here's a sandbox to reproduce the problem: https://kfkx5.csb.app/

Upvotes: 4

Views: 1478

Answers (1)

Quentin Grisel
Quentin Grisel

Reputation: 4987

[Edit]: I just found this codePen. It does exactly what you are looking for :)


I guess what you are looking for is :

window.scrollTo(0,document.body.scrollHeight);

instead of :

myRef.current.scrollTop = myRef.current.scrollHeight;

Of course, you need to change document.body.scrollHeight by the scrollable block. You can probably clean up a bit of code if your refs aren't used for anything else.

Here is the repro on Stackblitz. I only changed the line above from your own code.

P.S. : I got this answer from this SO thread :)

Upvotes: 1

Related Questions