1

I have a state the is an array of strings, containing all the messages recived. And a useEffect that triggers when a new message is recived. So I try to use set state to append the new message to the message board but it generates a starnge result.

Original idea: spreading the contents to the state as usual.

    useEffect(() => {
        socket.on("recive_message", (data) => {
            setBoard((chats) => [data.message, ...chats])
        })
    }, [])

but this way there is no appending and the chat board first element is being replaced with the incoming message.. So I tried another way I saw on the internet:

    useEffect(() => {
        socket.on("recive_message", (data) => {
            setBoard([data.message, ...board])
        })
    }, [])

And this works just fine. What is the difference between the two syntax?

TMarciDev
  • 73
  • 6
  • Using the callback form allows you to use the previous value in state, even if the previous value hasn't been rendered yet. here the full answer: https://stackoverflow.com/a/64361392/11528064 – adel Feb 16 '23 at 14:08
  • I see, but is the because we are inside of a useState hook? – TMarciDev Feb 16 '23 at 14:14

1 Answers1

1

the first example is correct, are you initializing the state with an empty array? if not that can lead to some issue (you can't spread undefined). the second example is incorrect because you don't have the variable board as useEffect dependency, so it won't update and will always have the initial value.

e.pacciani
  • 206
  • 1
  • 6
  • It is interesting because I do initialize the state with an emty array. And only the second method works correctly for me. If I output the board array content right before the setBoard call it shows an empty array. So the array is re-initialized to an empty array somehow. That is why I think useState has something to do with it.. – TMarciDev Feb 16 '23 at 16:36