Reputation: 856
i have a simple react demo where to show websocket messages, but the .map function inside return statements returns nothing. No errors and no messages. Can anyone explain where the problem is in here?
const [messages, setMessages] = React.useState([])
//push the websocket messages response to const messages
const addMessage = (message) => {
let n = messages;
let d = message;
n.push(d);
setMessages(n)
//the following both works as expected
messages.map((item) => {
console.log('message', item.message)
})
messages.map((message, index) =>
console.log(message,index)
)
}
Now the problem in return statement: Here was nothing returned.
return (
<div>
{
messages.map(function(message, index){
return (<p id={'t'+index}>{message.message}</p>)
}),
messages.map((message, index) =>{
return (<p id={'z'+index}>{message.message}</p>)
})
}
</div>
)
Maybe the return statement is not rerendered after receiving websocket message? I hope anyone have an idea and can explain the problem.
Upvotes: 1
Views: 861
Reputation: 203447
You are mutating the messages
state array by pushing directly into it and saving it back into state. The messages
array reference never changes! React uses shallow object reference equality to help determine when the DOM should be updated. If the reference never updates then React bails on rerendering.
const [messages, setMessages] = React.useState([])
//push the websocket messages response to const messages
const addMessage = (message) => {
let n = messages; // <-- reference to state
let d = message;
n.push(d); // <-- state mutation
setMessages(n). // <-- saved back into state
...
}
Always shallow copy state that is being updated. Use a functional state update to update from the previous state
const [messages, setMessages] = React.useState([])
//push the websocket messages response to const messages
const addMessage = (message) => {
setMessages(messages => [
...messages, // <-- shallow copy messages array
message, // <-- and append new message
])
...
}
Upvotes: 3
Reputation: 1756
I think you should try:
let n = [...messages];
instead
let n = messages;
Upvotes: 1