tienda.js
const initialState = { messagelist: [] } const reducerAllMessages = (state=initialState, action) => { if(action.type === "newMessage") { console.log("state", state); return {...state, messagelist:[...state.messagelist, action.payload]} } return state; } const store = createStore(reducerAllMessages) export default store const [data, setData] = useState([]); const messages = useSelector((state) => state.messagelist) const dispatch = useDispatch() useEffect(() => { socket.on("user-to-admin", (payload) => { console.log("socket payload", payload); // setData([...data,{ who: "him", message: payload.message} ]); dispatch({type:"newMessage",payload:payload}) }, [messages] ); }); let list = () => { if (data === undefined ) { } else { return messages.map((e) => <ChatBubble who={e.who} message={e.message} />); } }; return <ul>{list()}</ul>; }IMAGEN
https://i.stack.imgur.com/mui6M.png
No sé por qué está causando que se multipliquen los elementos en la matriz cada vez que presiono elementos
Su controlador de eventos de socket está envuelto en useEffect, que no tiene dependencias. Cuando envía el evento 'newMessage', y es procesado por la tienda y se envían actualizaciones al segmento de estado del mensaje, su componente se vuelve a procesar. La nueva representación hace que se adjunte un nuevo controlador de eventos de socket, lo que duplica sus mensajes después de cada evento. Cambiar su código al siguiente fragmento debería solucionar esto:
useEffect(() => { socket.on("user-to-admin", (payload) => { console.log("socket payload", payload); // setData([...data,{ who: "him", message: payload.message} ]); dispatch({type:"newMessage",payload:payload}) }, [messages] ); }, []);Ahora useEffect solo se ejecutará cuando el componente se represente por primera vez.