'useEffect with dependency called infinitely

I have an alert that I want to hide in a timeout function after an item is added/removed from a list.

Instead of cleaning up the timeout function, useEffect ends up in a loop.

function App() {
  const [item, setItem] = useState({
    id: "",
    name: "",
  });
  const [list, setList] = useState([]);
  const [isEditing, setISEditing] = useState(false);
  const [alert, setAlert] = useState({
    active: false,
    type: "",
  });

  const addToList = (e) => {
    e.preventDefault();
    setAlert({ active: true, type: "success" });
    let newItem = { id: new Date().getTime().toString(), name: item };
    e.preventDefault();
    setList([...list, newItem]);
  };

  const removeFromList = (id) => {
    setAlert({ active: true, type: "danger" });
    setList(list.filter((item) => item.id !== id));
  };

  useEffect(() => {
   const timeout = setTimeout(() => {
      setAlert({ active: false, type: "" });
    }, 3000);
    return () => clearTimeout(timeout);
  }, [alert.active]);

I have a similar example below, but there useEffect did not end up in a loop, although I change the state in useEffect. What exactly is the difference between the two?

const SingleColor = ({ rgb, weight, index }) => {
  const [alert, setAlert] = useState(false);
  const hex = rgbToHex(...rgb);

 useEffect(() => {
    const timeout = setTimeout(() => {
      setAlert(false);
    }, 3000);
    return () => clearTimeout(timeout);
  }, [alert]);

  return (
    <article
      className={`color ${index > 10 && "color-light"}`}
      style={{ backgroundColor: hex }}
      onClick={() => {
        setAlert(true);
        navigator.clipboard.writeText(hex);
      }}
    >
      <p className="percent-value">{weight}%</p>
      <p className="color-value">{hex}</p>
      {alert && <p className="alert">Copied to clipboard!</p>}
    </article>
  );
};

export default SingleColor;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source