I am currently working on a form where the steps slide in as cards. For example, when transitioning from step 1 to step 2, the card appears from the right, and when going back from step 3 to step 2, the card slides in from the left.
However, I am facing an issue where the direction is always "one step behind". It takes two clicks in one direction for the transition to catch up.
Whenever the prev/next buttons are clicked, handleActive() function is triggered:
const handleActive = (num, text) => {
setDirection(text)
setActive(num)
}
Here's an example of a card division:
<div className={active === 2 ? 'card-active' : 'card-' + direction}>
<h4>Step {active}</h4>
<input className='input' type="text" name="name" id="name" placeholder='Name' />
<input className='input' type="text" name="address" id="address" placeholder='Address' />
<input className='input' type="text" name="phone" id="phone" placeholder='Phone' />
<button className='btn' type="button" onClick={() => handleActive(-1, 'from-left')}>PREV</button>
<button className='btn' type="button" onClick={() => handleActive(1, 'from-right')}>NEXT</button>
</div>
CSS:
.card-from-right {
...
left: 35%;
transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;
}
.card-from-left {
...
left: 25%;
transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;
}
.card-active {
...
left: 30%;
}
I have experimented with async/await in the handleActive() function and tried using useEffect, but only setTimeout seems to work (though it feels like a hacky solution).
const handleActive = async (num, text) => {
await setDirection(text)
await setActive(num)
}
const handleActive = async (num, text) => {
await setDirection(text)
setTimeout(() => {
setActive(num)
}, 600);
}
I am looking for suggestions on how to pause (and possibly modify the DOM) to update the classNames before executing setActive(). Even though Console.log and the source code display the correct classNames, they somehow don't get updated in time before setActive() is run...