When two components need the same value, neither can own it. Move the state to their closest common parent and pass it down: the value as one prop, the setter as another. The children become controlled by the parent, and there is exactly one copy of the truth.
function Chat({ contact }) {
const [text, setText] = useState('');
return <textarea value={text} onChange={e => setText(e.target.value)} />;
}
function Messenger({ contacts }) {
const [to, setTo] = useState(contacts[0]); // the shared value lives here
return (
<>
<ContactList contacts={contacts} selected={to} onSelect={setTo} />
<Chat key={to.id} contact={to} /> {/* new key: new Chat, empty draft */}
</>
);
}ContactList no longer remembers which row is highlighted; it renders selected and reports clicks through onSelect. That is the whole pattern, and it is why so much React 7,897 code ends up as a stateful container with stateless leaves.
The key on <Chat> solves a different problem. React identifies a component by its position in the tree, so switching contacts would reuse the same Chat and keep a half-typed message meant for someone else. A changing key says the two are not the same component: the old unmounts, its state and effects go, and a fresh one mounts with text back to ''.
