For some reason, only the last element of my messages state array is rendering. Whenever I call addMessage and print the current state of messages, an empty array always prints out. After I push the new message to the state array, the array prints out with one message. Why is my messages state not properly saving and resetting to an empty array?
const ChatApp = () => {
const [messages, setMessages] = React.useState([]);
useEffect(() => {
ioClient.emit('join', { roomid: roomId });
ioClient.emit('connected', { roomid: roomId });
}, []);
ioClient.on('message', (msg) => {
const messageObject = {
username: msg.from,
message: msg.body,
timestamp: msg.timestamp
};
addMessage(messageObject);
});
ioClient.on('send', (con) => {
for (var key in con.arra) {
var value = con.arra[key];
const messageObject = {
username: value.from,
message: value.body,
timestamp: value.timestamp
};
addMessage(messageObject);
}
});
const sendHandler = (message) => {
var res = moment().format('MM/DD/YYYY h:mm a').toString();
ioClient.emit('server:message', {
from: senderFullName,
body: message,
timestamp: res,
roomId: roomId
});
};
const addMessage = (message) => {
console.log(messages);
let messagess = [...messages, message];
setMessages(messagess);
console.log(messagess);
};
return (
<div className="landing">
<Container>
<Row className="mt-5">
<Col md={{ span: 8, offset: 2 }}>
<Card style={{ height: '36rem' }} border="dark">
<Messages msgs={messages} />
<Card.Footer>
<ChatInput onSend={sendHandler}></ChatInput>
</Card.Footer>
</Card>
</Col>
</Row>
</Container>
</div>
);
};
ChatApp.defaultProps = {
username: 'anonymous'
};
const mapStateToProps = (state) => {
return {
authUser: state.auth.user,
profile: state.profile.profile
};
};
export default connect(mapStateToProps)(ChatApp);
Messages Component
import React from 'react';
import Message from './Message';
class Messages extends React.Component {
componentDidUpdate() {
// There is a new message in the state, scroll to bottom of list
const objDiv = document.getElementById('messageList');
objDiv.scrollTop = objDiv.scrollHeight;
}
render() {
// Loop through all the messages in the state and create a Message component
const messages = this.props.msgs.map((message, i) => {
return (
<Message
key={i}
username={message.username}
timestamp={message.timestamp}
message={message.message}
fromMe={message.fromMe} />
);
});
return (
<div className='messages' id='messageList'>
{ messages }
</div>
);
}
}
Messages.defaultProps = {
msgs: []
};
export default Messages;
Message Component
import React from 'react';
import Container from 'react-bootstrap/Container';
import Image from 'react-bootstrap/Image';
import Card from 'react-bootstrap/Card';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Button from 'react-bootstrap/Button';
import Media from 'react-bootstrap/Media';
class Message extends React.Component {
render() {
let now = this.props.timestamp;
return (
<ul className="list-unstyled">
<Media.Body>
<h6 className="font-weight-bold">{ this.props.username }</h6>
<p>
{ this.props.message }
</p>
<p className="small text-muted">
{now}
</p>
</Media.Body>
</Media>
</ul>
);
}
}
Message.defaultProps = {
message: '',
username: '',
to: '',
fromMe: false
};
export default Message;