0

The useEffect would run more than once for some reason (usually twice) and would print my message twice (or more). I have tried multiple solutions even with useMontainEffect but the result is always the same. Any solutions?

import './App.css';
import io from 'socket.io-client'
import { useEffect, useRef, useState } from 'react'
import React from 'react';
import ReactDOM from "react-dom/client";


const socket = io.connect("http://localhost:3001");

function App() {
  const [message, setMessage] = useState("");
  const [state, setState] = useState([]);
  const [chat, setChat] = useState([]);
  const socketRef = useRef();
  const sendMessage = () => {
    socket.emit("send_message", { message });
  };

  const renderChat = () => {
    return (
        chat.map(msg => {
            return (
                <h3>{msg.message['message']}</h3>
            )
        })
    )
}


useEffect(() => {
  socket.on("receive_message", message => {
    setChat(prevState => [...prevState, {message}]);
  });
}, [socket])


  return (
    <div className="App">
      <input placeholder="Message..." onChange={(event) => {
        setMessage(event.target.value);}}
        />
      <button onClick={sendMessage}>Send Message</button>
      <h1>Message:</h1>
      {renderChat()}
    </div>
  );
}

export default App;

Venoz
  • 65
  • 9
  • Does this answer your question? [React Hooks: useEffect() is called twice even if an empty array is used as an argument](https://stackoverflow.com/questions/60618844/react-hooks-useeffect-is-called-twice-even-if-an-empty-array-is-used-as-an-ar) – Konrad Sep 27 '22 at 18:20
  • Its caused due to the Strict Mode. Disable it and try again. – Nirmal Kumar Sep 27 '22 at 18:21
  • @NirmalKumar disabling the Strict Mode is exactly what you shouldn't do – Konrad Sep 27 '22 at 18:24

2 Answers2

1

In strict mode the component will be mounted, unmounted, then re-mounted. You can add a cleanup function. The double invocation however is expected.

useEffect(() => {
  const listener = message => {
    setChat(prevState => [...prevState, {message}]);
  };
  socket.on("receive_message", listener);
  return () => socket.off('receive_message', listener);
}, [socket])

aziz punjani
  • 25,586
  • 9
  • 47
  • 56
0

If u want to check, U can turn off the strict mode and check exactly how many times the useEffect call back function runs

Note : but don't always turn off the strict mode because

--> strict mode is actually because if we forgot any cleanup function in useEffect , ui behaves differently

--> with that only we came to know that we did something mistake

--> strict mode is present in only development mode, it won't be in production mode

lucky
  • 31
  • 8