Search code examples
reactjssetintervaluse-effect

A function written in useEffect printing a value twice when the if condition got true. Can anyone help me to solve it?


  • I want to create a reminder feature of the task. Basically the idea is that in my note app while any user creating their task, at that time i ask a reminder date-time from it and then store it into DB and when that date-time comes then i will push a email of that particular note.

  • To achieve this, my logic is i convert the DB reminder date-time in seconds and i get the current date-time and also convert it into seconds. After that i do operation - let msgTime = remind - currentDateSec. where currentDateSec is current date-time and remind is the DB date-time. and then store it in msgTime variable.

  • When msgTime == 0 then i will push the reminder mail to user register mail id. But here i wrote Hi for the the testing purpose and this Hi is printing 2 times in the console, and i don't want it. I want to print it only one time only.

  • To check every second i called my function in setinterval and run it after 1000ms.

      const [notes, setNotes] = useState([]);
    
      useEffect(() => {
      function checkReminder() {
        let remind = 0;
        let currentDate = new Date();
        let currentDateSec = Math.floor(currentDate.getTime() / 1000);
    
        for (let index = 0; index < notes.length; index++) {
          remind = notes[index].reminderTime;
          let msgTime = remind - currentDateSec;
          console.log(msgTime);
    
          if (msgTime === 0) {
            console.log("hi");
            clearInterval(interval);
          }
        }
      }
      const interval = setInterval(() => {
        checkReminder();
      }, 1000);
    })
    
  • This code is for fetching the notes from database.

const fetchNotes = async () => {
    try {
      let res = await axios.get("/api/notes", config);
      setNotes(res.data);
      // console.log(notes); 
    } catch (err) {
      setError(err.response.res);
    }
  };

Note : I already removed React.StrictMode


Solution

  • add this return statement to your useEffect function and you will be fine:

    useEffect(() => {
            function checkReminder() {
                let remind = 0;
                let currentDate = new Date();
                let currentDateSec = Math.floor(currentDate.getTime() / 1000);
    
                for (let index = 0; index < notes.length; index++) {
                    remind = notes[index].reminderTime;
                    let msgTime = remind - currentDateSec;
                    console.log(msgTime);
    
                    if (msgTime === 0) {
                        console.log("hi");
                        clearInterval(interval);
                    }
                }
            }
            const interval = setInterval(() => {
                checkReminder();
            }, 1000);
    
            return () => {
                clearInterval(interval);
            };
        })
    

    It's sometimes necessary to return the cleanup function from useEffect to avoid further triggers.