Closed devinrbopp closed 2 years ago
So, first thing I noticed is that you're storing components in an array in state. Instead, you should be storing the data for those components, then mapping over that data and producing one message component for each item in the array. I also wanted to remind you of this syntax we used in the hooks lesson for updating state based on the previous state, it looked like this:
const addSprinkles = () => {
setDonut(prevDonut => prevDonut + ' with sprinkles')
}
That syntax might possibly be better used with the spread operator in your case since you're using an array, just to continue with my example:
const addSprinkles = () => {
setDonut(prevDonut => ...prevDonut += ' with sprinkles')
}
That's just another thing you can attempt in the case that using the first syntax doesn't solve the problem. So, steps are as follows:
Message
component eachapplying this now, will report back!
useEffect(() => {
socket.on('broadcast', data => {
console.log(messagesData)
let previousData = messagesData
let newData = previousData.concat([data])
setMessagesData(newData)
// console.log('THESE ARE THE OLD MESSAGES: ', messages)
// let oldMessages = messages
// let newMessage = [<Message key={String(Math.random())} sender={data.sender} message={data.message} />]
// let updatedMessages = oldMessages.concat(newMessage)
// setMessages([...updatedMessages])
})
}, [socket])
const messages = messagesData.map((data, i) => {
return <Message key={i} sender={data.sender} message={data.message} />
})
Divided it up and renamed. I stuck with this syntax because the spread operator wasn't working. What's scaring me here is the console.log(messagesData)
, which returns a blank array every time. So it's not that my setMessagesData is overwriting it, but that it's already emptied out every time I get to it. Does that make sense?
It's still rendering the most recent message across all open client sockets, which is good!
Weirdly enough, if I put a console.log above socket.on, it only prints once, when the page first renders, even though the socket.on listener is getting triggered every time a message is sent.
Is this resolved?
Not yet, Timm and I are working on it!
Still working on this w/o Timm, will post an update or tag you when something has changed.
@TaylorDarneille I posted on stackoverflow, if you're bored and have any ideas let me know please~!
What stack are you using?
(ex: MERN(mongoose + react), DR(django + react), PEN, etc.)
MERN
What's the problem you're trying to solve?
I am storing chat messages in state. I need to use useEffect with socket.io to process incoming messages, but every time it is triggered it wipes the state, so it only contains the most recent message. I've been working on this all morning, and part of last night.
Post any code you think might be relevant (one fenced block per file)
If you see an error message, post it here. If you don't, what unexpected behavior are you seeing?
No error. Unexpected behavior is that only the most recent message will render/get stored in state. Previous messages are lost.
What is your best guess as to the source of the problem?
I looks like it's because the useEffect is wiping the state, but I have no idea why that would happen.
What things have you already tried to solve the problem?
I've tried moving functions to different components, moving things in and out of the useEffect, creating additional temp variables, no luck. The one thing that worked was removing the useEffect entirely, but that causes duplicate socket.on triggers that grow exponentially and slow the app down after 5 messages.