Reputation: 1059
I have a chat component that connects to a socket and retrieves messages. On the event allMessages
I set the messages to the state via setMessages
, works as expected. My issue is when the event newMessage
is called it seems messages
is empty. How can I add the new message to the list of current messages?
export default function ChatPage(props) {
const {socket} = useSelector((state) => state.socket);
const [messages, setMessages] = useState([]);
const [message, setMessage] = useState('');
const [chatId, setChatId] = useState(null);
const classes = useStyles();
function handleSubmit(event) {
event.preventDefault();
if (socket && chatId) {
socket.emit('submitNewMessage', ({content: message, chatId: chatId}));
setMessage('');
};
};
useEffect(async () => {
let res = await api.getChatId({friendId: props.match.params.userId});
if (res.status === 200 && res.data.chatId) {
setChatId(res.data.chatId);
};
},[]);
useEffect(() => {
if (chatId && socket) {
socket.emit('joinChat', chatId);
socket.on('allMessages', (allMessages) => {
setMessages([...allMessages]);
});
socket.on('newMessage', (newMessage) => {
setMessages([...messages, newMessage])
});
};
}, [chatId, socket]);
return (
<Grid container className={classes.root}>
<Navbar />
<main className={classes.main}>
<Grid>
<Typography variant='h4'>
Chat Page {props.match.params.userId}
</Typography>
{messages && messages.map(message => (
<Typography variant='h4'>
{message.content}
</Typography>))
}
<Grid item>
<TextField
id="input"
name="message"
value={message}
onChange={(event)=> setMessage(event.target.value)}
label="Multiline"
multiline
rows={4}
defaultValue="Default Value"
variant="outlined"
/>
<Button type="submit" onClick={handleSubmit}>Submit</Button>
</Grid>
</Grid>
</main>
</Grid>
);
};
Upvotes: 0
Views: 382
Reputation: 4832
This seems to be a scoping issue. Pass a function into setMessages instead:
setMessages(msgs => [...msgs, newMessage])
The msgs argument will give you access to the current value, and the return value is the new state you wish to be set.
Upvotes: 1