Message Composer with Auto-Scroll
The compose area sends messages but does nothing to manage focus or scroll position afterward. Add two refs to fix both.
Requirements
- Store a ref on the
<textarea> element and call ref.current?.focus() in send after clearing the draft.
- Store a ref on a sentinel
<div> at the bottom of the thread and call ref.current?.scrollIntoView({ behavior: "smooth" }) inside a useEffect that runs whenever messages changes.
- Keep Enter (without Shift) as a send shortcut.
- Leave the textarea controlled with
draft state — do not switch to an uncontrolled input.
Key insight
Focus can happen synchronously in the event handler because the textarea stays mounted. Scroll must happen in an effect because it depends on the new message rendering to the DOM first.
Progressive hints
useRef<HTMLTextAreaElement>(null) gives you a typed ref; attach it with ref={inputRef}.
- Call
inputRef.current?.focus() at the end of send — after setDraft("").
useEffect(() => { bottomRef.current?.scrollIntoView(...) }, [messages]) runs after every render that changes messages.
What to explain
Why can't you place the scrollIntoView call directly in send, right after setMessages?