'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 ? 
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 |
|---|
