0

store.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

messagelist.js

  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>;
}

IMAGE

https://i.sstatic.net/mui6M.png

Don't know why it is causing to multiply the elements in the array every time i am pushing elements

1 Answer 1

1

Your socket event handler is wrapped in useEffect, which does not have any dependencies. When you dispatch 'newMessage' event, and it is processed by store and updates to message state slice are pushed, your component gets re-rendered. Re-rendering causes a new socket event handler to be attached, thus doubling your messages after every event. Changing your code to below snippet should fix this:

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]
  );
}, []);

Now useEffect would only run when component is rendered the first time.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes it is the right answer.
Good to know. In general right answers should be marked as accepted by the question owners.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.