'In my code snippet why useEffect shows useState variable as one valuel, but when I use this variable in a logic it's another value?

I'm very confused, I have parent and a child component. What It's doing is if condition is matched in a child component, then it add's child component to array. When there is transitionis in child component it calls a deleteMe function in parent component. Real problem what I deal with is a line deleteMe function, line where I have console.log. This line ALWAYS prints me that there is [{...}] one element in array. While useEffect hook shows me that updating an array happens just fine.

Why when I call same variable it gives me different results from deleteMe func and usEffect ? here is console.log

import { FC, useRef, useState, ReactElement, useEffect} from "react"
import "./marquee.scss"
import MarqueeItem from "./Item/Item"

const Marquee: FC <{text: string}> = ({ text }) => {
    let cnt = useRef<number>(0)
    const [marquees, setMarquees] = useState< ReactElement[]>(
        [<MarqueeItem
            key={cnt.current} 
            launchNext={() => launchNext()}
            deleteMe={() => deleteMe()} 
            text={text}/>]
    )

    const deleteMe = () => {
        console.log(marquees, "inside deleteMe")
        if(marquees.length > 5) { // Here I have an issue. Cause "marquees" is ALWAYS 1 element !
            console.log("More then 5") 
        }
    }

    const launchNext = () => {
        cnt.current = cnt.current + 1;
        setMarquees(oldArr => [...oldArr, <MarqueeItem key={cnt.current} deleteMe={() => deleteMe()} launchNext={() => launchNext()} text={text}/>])
    }

    useEffect(() => {
        console.log(marquees, "useEffect")
    })

    return <div className="marquee">
        { marquees }
    </div>
} 

export default Marquee

Child component :

const MarqueeItem: FC<IProps> = ({text, launchNext, deleteMe }) => {
    let observed = useRef<HTMLParagraphElement>(null)

    const isReady = <T extends number>(currLeft: T, header_width: T , p_width: T): boolean => {
        return currLeft < 0 && (p_width + currLeft) < header_width ? true : false
    }

    useEffect(() => {
        const marquee = observed.current!

        const transitionendListener = () => deleteMe()
        marquee.addEventListener("transitionend", transitionendListener) // calling deleteMe when transition is over

        const parantNode = marquee.parentNode as Element
        const header_width = parseInt(getComputedStyle(parantNode).width)
        const p_width = parseInt(getComputedStyle(marquee).width)
        
        marquee.style.left = -p_width + "px"

        const intervalRead = setInterval(() => {
            let currLeft = parseInt(getComputedStyle(marquee).left)
            if(isReady(currLeft, header_width, p_width)) {
                launchNext() // adding a new element to array in parent when it's good condition to add
                clearInterval(intervalRead)
            }
        }, 400)

        return () => {
             marquee.removeEventListener("transitionend", transitionendListener)
        }
    }, [observed, launchNext, deleteMe])

    return <p ref={observed} className="marquee__text">{text}</p>
}

export default MarqueeItem


Sources

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

Source: Stack Overflow

Solution Source