Real World Example

Real World: WhatsApp Web: scroll to the newest message

When a new message arrives, the chat scrolls to the bottom and the input keeps focus. Both use refs to the DOM.

function ChatWindow({ messages, onSend }) {
  const endRef = useRef(null);
  const inputRef = useRef(null);

  useEffect(() => {
    endRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);

  const send = () => {
    onSend(inputRef.current.value);
    inputRef.current.value = '';
    inputRef.current.focus();
  };

  return (
    <div>
      {messages.map((m) => <p key={m.id}>{m.text}</p>)}
      <div ref={endRef} />
      <input ref={inputRef} />
      <button onClick={send}>Send</button>
    </div>
  );
}