I want to return the first 2 objects of an array of 4 objects then add the other two objects with 5 seconds in between.
note: I am reversing the copied array revEvents with reverse() as items are in descending order by date/time, the most recent item goes on top.
My current issue is the first two objects are displayed ok, then after 5 seconds, it loads only the third object and it stops.
useEffect(() => {
let ms = 3000
let i = 0
let displayedEvents = [...props].splice(i, 2)
setEventsProps(displayedEvents.reverse())
const interval = setInterval(() => {
if (++i <= props.length) {
displayedEvents = props.splice(0, i + 2)
setEventsProps(displayedEvents.reverse())
}
}, ms)
return () => { clearInterval(interval) }
}, [])
//JSX as below
displayedEvents.map(event () => ...etc
I'd like to share an improved solution.
useEffect(() => {
const ms = 5000
let i = 2
const displayedEvents: IEventsProps = props.slice(0, 2)
setEventsProps(displayedEvents.reverse())
let interval: NodeJS.Timeout = setInterval((): void => {
if (i < props.length) {
displayedEvents.push(props[i])
setEventsProps(displayedEvents.reverse())
i += 1
} else {
clearInterval(interval)
interval = null
}
}, ms)
return () => { if (interval) { clearInterval(interval) } }
}, [])
This avoids making unnecessary new arrays by mutating the same array, and also clears the interval when the work is done, so it doesn't run forever.
Fixed this issue, instead of using the splice() function I needed to use the slice() function instead.
The code remains the same, added typescript for anyone who find this.
useEffect(() => {
let ms: number = 5000
let i: number = 0
let displayedEvents: IEventsProps = [...props].slice(i, 2)
setEventsProps(displayedEvents.reverse())
const interval: NodeJS.Timeout = setInterval((): void => {
if (++i <= props.length) {
displayedEvents = props.slice(0, i + 2)
setEventsProps(displayedEvents.reverse())
}
}, ms)
return () => { clearInterval(interval) }
}, [])