Can you tell me why my useState is still empty? It doesn't want to update it. I'm using setInteraval and a function to update data and want to set useState at the current time, but useState ignores formatTime in setTimeOut(res) . Can you tell me how to fix it?
EDIT: If I put the number into useState
const [timeOut, setTimeOut] = useState(30)
It appears for a second and then disappears and I have empty fields. It seems like setInterval deletes everything inside, so how to fix it?
const Timer = ({item}) => { const [timeOut, setTimeOut] = useState('') // << doent want to update it from // formatTime function console.log(timeOut) // still empty useEffect(() => { if (status !== 'unPaid') return; const timer = window.setInterval(() => { setTimeOut(formatTime(createdAt)); }, 1000); return () => window.clearInterval(timer); }, [createdAt, status]); const formatTime = (time) => { console.log(time) // 2023-07-25T23:39:39.253Z // const timer = new Date(time).getTime() + 1800000 const timer = new Date(time).getTime() + 250000 let countDown = new Date().getTime() let distance = timer - countDown let min = Math.floor((distance % (1000*60*60) / (1000*60))) let sec = Math.floor((distance % (1000*60) / (1000))) let res = Math.abs(min) + ':' + Math.abs(sec) console.log(res) // 4:50 setTimeOut(res) // <<<<< it doesnt want to apdate my useState }
P粉1037395662023-09-15 17:42:24
This is most likely because you are setting the state within a timeout.
Another problem is that you are calling setTimeout inside it.
Instead, use a function that returns a new value based on the previous state.
useState
Accepts a function that receives previousState
as a parameter
const [count, setCount] = useState(0); useEffect(() => { window.setTimeout(() => { setCount((prevValue) => { return prevValue + 1; // what you return here, will be the new state. }) }, 1000) }, []);
P粉9900084282023-09-15 09:23:00
Looks like the problem is that setInterval runs every second and updates the status (timeOut) every second.
Also, in the formatTime function, you are using the current time (new Date().getTime()) instead of the createdAt time. Therefore, the status is constantly updated with new values every second.
This is the updated code.
const Timer = ({ item }) => { const [timeOut, setTimeOut] = useState(''); useEffect(() => { if (status !== 'unPaid') return; const timer = window.setInterval(() => { setTimeOut(formatTime(createdAt)); }, 1000); return () => window.clearInterval(timer); }, [createdAt, status]); const formatTime = (time) => { const timer = new Date(time).getTime() + 250000; const currentTime = new Date().getTime(); const distance = timer - currentTime; let min = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); let sec = Math.floor((distance % (1000 * 60)) / 1000); let res = Math.abs(min) + ':' + Math.abs(sec).toString().padStart(2, '0'); return res; }; return <div>{timeOut}</div>; };