Sometimes I want a parent element to keep track of the children’s state. For example, a state that’s a list where each item corresponds to exactly one DOM-child. In my application this is a multi-message LLM-chat window where a websocket accepts tokens and appends them to the response to one of the messages a user had input – e.g. like chatgpt where tokens appear slowly. Usually this should be the last message the user wrote, but due to race conditions or unforeseen future features it could be any.
This situation is similar to this simple variant:
function Child({number, id}) {
console.log(`render ${number}`);
return <p key={`number-${id}`}>{number}</p>
}
function Parent() {
var [numbers, setNumbers] = useState([1,2,7,9]);
if (numbers[1] !== 10) {
// update to one item in `numbers`, e.g. as per a websocket message
setTimeout(() => {
setNumbers(numbers.slice(0, 1).concat([10]).concat(numbers.slice(2)));
}, 4000)
}
//implicit structure that i-th child should only refresh on state change of `numbers[i]`.
return numbers.map((number, id) => <Child {...{number, id}}/>);
}
However, setNumbers
will trigger render updates of all children, particularly if (semantic) equality of items can’t be measured. Is there an elegant design pattern or method to allow for only the appropriate child to be rendered again while keeping the setTimeout
(or websocket) in control of the parent?
(This is a question that has been stuck with me for some time – apologies if my way is abuse of React or I plainly don’t understanding something)
3