S
S
SerjSkachkov2020-10-16 01:03:57
React
SerjSkachkov, 2020-10-16 01:03:57

How to reset setInterval in a timer?

There is a countdown counter where the date falls and the time counts down.

error index.js:1 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in TodoListItemInner (at TodoList.jsx:11)

How to beat it?

import React, { useEffect, useState, memo } from "react";
import classNames from "classnames";

import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faTrash,
  faEdit,
  faEllipsisV,
} from "@fortawesome/free-solid-svg-icons";

const TodoListItemInner = ({
  id,
  date,
  name,
  onUpdateModalOpen,
  onDeleteModalOpen,
}) => {
  const [timeLeft, setTimeLeft] = useState(new Date(date).getTime());
  const [dateNow] = useState(new Date().getTime());

  useEffect(() => {
    const interval = setInterval(() => {
      setTimeLeft((prevDate) => prevDate - 1000);
    }, 1000);
  }, []);

  const formatDate = (date) => {
    const difference = date - dateNow;

    const days = Math.floor(difference / (1000 * 60 * 60 * 24));
    const hours = Math.floor((difference / (1000 * 60 * 60)) % 24);
    const minutes = Math.floor((difference / 1000 / 60) % 60);
    const seconds = Math.floor((difference / 1000) % 60);
    if (difference > 0) {
      return `${days} d : ${hours} h : ${minutes} m  : ${seconds} s`;
    } else {
      return "Time is left";
    }
  };

  const isLowerTime = dateNow + 1000 * 60 * 10 >= timeLeft;
  const isMediumTime = dateNow + 1000 * 60 * 60 >= timeLeft;

  const classes = classNames("list-item", {
    low: isLowerTime,
    medium: isMediumTime,
  });

  return (
    <li className={classes}>
      <div className="list-item-wrapper">
        <div className="list-item-content">
          <div className="list-item-name">{name}</div>
          <div className="list-item-date">
            <div className="list-item-deadline">
              Deadline: {new Date(date).toLocaleString()}
            </div>

            <div className="list-item-count">
              Time count: {formatDate(timeLeft)}
            </div>
          </div>
        </div>
        <div className="list-item-controls">
          <div className="list-item-area">
            <div className="list-item-switch">
              <FontAwesomeIcon icon={faEllipsisV} />
            </div>
            <div className="list-item-drop">
              <button onClick={() => onUpdateModalOpen(id)}>
                <FontAwesomeIcon icon={faEdit} />
              </button>
              <button onClick={() => onDeleteModalOpen(id)}>
                <FontAwesomeIcon icon={faTrash} />
              </button>
            </div>
          </div>
        </div>
      </div>
    </li>
  );
};

export const TodoListItem = memo(TodoListItemInner);

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2020-10-16
@SerjSkachkov

Add to useEffect . return () => clearInterval(interval);

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question