Home > Mobile >  Component Style Update Not Waiting on setTimeOut Function
Component Style Update Not Waiting on setTimeOut Function

Time:03-15

I have a div with three children, and a button that when pushed changes their relative position to slide over into frame. As a view slides over into frame, the other views should not only slide out, but also become hidden (to not take up vertical space).

Currently, I'm using the 'visibility' css property to show/hide the div after transition, but that doesn't collapse the height of the parent container as the hidden div still takes up vertical space.

enter image description here

Code Using 'Visibility' Property

useEffect(() => {
    updating position css attribute via style dict...
    
    switch(activePage) {
        case 1:
            setPageOneVisible(true)
            setTimeout(setPageTwoVisible(false), 500)
            break
        
        case 2:
            setPageTwoVisible(true)
            setTimeout(setPageOneVisible(false), 500)
            setTimeout(setPageThreeVisible(false), 500)
            break

        case 3:
            setPageThreeVisible(true)
            setTimeout(setPageTwoVisible(false), 500)
    }

}, [activePage])

Using the 'display: none' or 'height: 0' properties works in the sense that the parent container collapses, but for some reason, even if applying these properties using the setTimeOut() function to only trigger after the transition is completed, the divs get hidden instantaneously and don't wait for the timer.

enter image description here

Code Using 'Display' Property

useEffect(() => {
    setPageOnePosDict(prevState => ({
        ...prevState,
        ['display']: pageOneVisible ? 'block' : 'none'
    }))
    setPageTwoPosDict(prevState => ({
        ...prevState,
        ['display']: pageTwoVisible ? 'block' : 'none'
    }))
    setPageThreePosDict(prevState => ({
        ...prevState,
        ['display']: pageThreeVisible ? 'block' : 'none'
    }))
}, [pageOneVisible, pageTwoVisible, pageThreeVisible])

Why does react appear to ignore the useTimeOut function when the 'display' style is being added?

The JSX code for the 3 divs is:

<div id='screen1' className='relative w-full bg-blue-100 h-min overlap transition-all duration-500' style={pageOnePosDict}>
    <div className='w-full h-[400px] bg-transparent text-center'>
        <div className='pt-[200px]'>1</div>
    </div>
</div>
<div id='screen2' className='relative w-full bg-green-100 h-min overlap transition-all duration-500' style={pageTwoPosDict}>
    <div className='w-full h-[200px] bg-transparent text-center'>
        <div className='pt-[100px]'>2</div>
    </div>
</div>
<div id='screen3' className='relative w-full bg-purple-100 h-min overlap transition-all duration-500' style={pageThreePosDict}>
    <div className='w-full h-[100px] bg-transparent text-center'>
        <div className='pt-[40px]'>3</div>
    </div>
</div>

CodePudding user response:

The first argument to setTimeout should be a function, but you’re invoking the function and passing its return value to setTimeout. Invoking it triggers the change(s) immediately.

// do this
setTimeout(() => setPageTwoVisible(false), 500)

// not this
setTimeout(setPageTwoVisible(false), 500)
  • Related