I have the next code where i created a hook to handle the timeout function. The idea is, when the user will click on a button, the message should appear and to be cleared after an amount of time.
import "./styles.css";
import React, { useRef, useCallback, useState, useEffect } from "react";
const useTimer = () => {
const timer = useRef();
const fn = useCallback((callback, timeout = 0) => {
clearTimeout(timer.current);
timer.current = setTimeout(() => {
callback();
}, timeout);
}, []);
const clearTimeoutHandler = () => {
console.log("clear");
return clearTimeout(timer.current);
};
useEffect(() => {
return clearTimeoutHandler();
}, []);
return { fn, clearTimeoutHandler };
};
export default function App() {
const [state, setState] = useState(false);
const [list, updateList] = useState([]);
const timer = useTimer();
const removeItem = (id) => {
updateList((list) => list.filter((x) => x.id !== id));
timer.clearTimeoutHandler();
};
const onClickHandler = () => {
const id = new Date();
const element = {
id: id,
text: "text" + new Date()
};
updateList(list.concat([{ ...list, ...element }]));
timer.fn(() => {
removeItem(id);
}, 2000);
};
const bottomMess = () => {
setState({ m: "hi" });
timer.fn(
() => {
setState(undefined);
},
2000
);
};
return (
<div className="App">
<button onClick={bottomMess}>Open bottom message</button>
<button onClick={onClickHandler}>Open top message</button>
{list.map((d) => (
<h1>{d.text}</h1>
))}
{state && (
<div style={{ position: "absolute", bottom: 0 }}>
bottom message {state.m}
</div>
)}
</div>
);
}
ISSUE: when I click on Open top message button 3 times, only the last message disappears, but I expect all to be removed.
Where is the issue in the hook and how to make the hook workable?
demo: https://codesandbox.io/s/summer-fire-2xw0d5?file=/src/App.js