Reputation: 415
I'm attempting to make a chat function using material UI. I created a function where users can post new chat messages which are then sent through the reducer and then saved in the redux store. This process works as intended except for the fact that the new chat message only appears after the user refreshes the page. I'm wondering why my render function isn't being updated. Here's the main chat display.
const ChatFunction = (props) => {
const classes = useStyles();
const { user } = props;
const userMessages = props.userMessages || {};
};
const mapStateToProps = (state) => {
return {
user: state.user,
userMessages:
state.messages &&
state.messages.find(
(userMessages) => userMessages.otherUser.username === state.currentMessage
)
};
};
export default connect(mapStateToProps, null)(ChatFunction);
The postMessage
function is then passed through my reducer and my reducer function is called to add the new message to the messages array.
export const newMessage = (state, payload) => {
const { message, sender } = payload;
return state.map((userMess) => {
if (userMess.id === message.Id) {
userMess.messages.push(message);
userMess.latestMessageText = message.text;
return userMess;
} else {
return userMess;
}
});
};
So, does anyone know why this isn't refreshing properly?
Upvotes: 1
Views: 73
Reputation: 203466
You are mutating the user's messages
array when you directly push into it and mutate other properties.
export const newMessage = (state, payload) => {
const { message, sender } = payload;
return state.map((userMess) => {
if (userMess.id === message.Id) {
userMess.messages.push(message); // <-- mutation!!
userMess.latestMessageText = message.text; // <-- mutation!!
return userMess;
} else {
return userMess;
}
});
};
When updating state in react you need to shallow copy state and any nested state being updated into new object references to React's reconciliation works.
export const newMessage = (state, payload) => {
const { message, sender } = payload;
return state.map((userMess) => { // <-- shallow copy of state
if (userMess.id === message.Id) {
return { // <-- return new user message object
...userMess, // <-- shallow copy of previous user message object
messages: [message.text, ...userMess.messages], // prepend message, return new array
latestMessageText: message.text, // update property
};
} else {
return userMess;
}
});
};
Upvotes: 1