简体   繁体   中英

Why does .map function return nothing in react

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.

Issue

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

  ...
}

Solution

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
  ])

  ...
}

I think you should try:

let n = [...messages];

instead

let n = messages;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM