Estoy intentando hacer una función de chat usando la interfaz de usuario de material. Creé una función donde los usuarios pueden publicar nuevos mensajes de chat que luego se envían a través del reductor y luego se guardan en la tienda redux. Este proceso funciona según lo previsto, excepto por el hecho de que el nuevo mensaje de chat solo aparece después de que el usuario actualice la página. Me pregunto por qué mi función de renderizado no se actualiza. Aquí está la pantalla de chat principal.
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); Luego, la función postMessage se pasa a través de mi reductor y se llama a mi función reductora para agregar el nuevo mensaje a la matriz de mensajes.
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; } }); };Entonces, ¿alguien sabe por qué esto no se actualiza correctamente?
Está mutando la matriz de messages del usuario cuando presiona directamente y muta otras propiedades.
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; } }); };Al actualizar el estado en reaccionar, necesita copiar el estado superficial y cualquier estado anidado que se actualice en nuevas referencias de objetos para los trabajos de reconciliación de React.
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; } }); };