Given the state
const [messages, setMessages] = useState({
ReactJS: [],
NestJS: [],
Typescript: [],
MySQL: [],
Neo4j: [],
Redis: [],
ELK: [],
Docker: [],
Kubernetes: [],
AWS: [],
SocketIO: [],
});
Then the following is a way to update a specific room via a roomKey identifier nested in the state object. In React when you update state you must always return a new object reference, and this includes any nested state/properties that are being updated. array.prototype.push mutates the original array, it doesn't create a new array reference for React purposes.
setMessages(messages => ({
...messages, // <-- shallow copy state
// copy existing nested state array into new array and append new element
[roomKey]: [...messages[roomKey], newMessage],
}));
An alternative to the array literal is to use array.prototype.concat, which does return a new array.
setMessages(messages => ({
...messages, // <-- shallow copy state
// copy existing nested state array into new array and append new element
[roomKey]: messages[roomKey].concat(newMessage),
}));
Note: This assumes your roomKey variable will reference one of the keys actually defined in your state. If you use an unspecified key then messages[unknownKey] will be undefined. In this case, if you've truly dynamic keys, then you can provide a fallback value to spread into state.
setMessages(messages => ({
...messages, // <-- shallow copy state
// copy existing nested state array into new array and append new element
[roomKey]: [
...messages[roomKey] || [], // <-- provide fallback
newMessage,
],
}));
roomnameproperty.TypeError: messages[roomKey] is not iterable.