Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

195
Vistas
When updating className css transition "one step behind"

I have a form that "slides in" the different steps as cards, e.g. when moving from step 1 to step 2 the card appears from the right, and when moving back from e.g. step 3 to step 2 the card slides in from the left.

My problem is that the direction is "one step behind", it takes two clicks in one direction for the transition to catch up.

When the prev/next buttons are clicked handleActive() is called:

const handleActive = (num, text) => {
   setDirection(text)
   setActive(num)
}

An example of a card div

<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 tried async/await in the handleActive() function and useEffect, but the only thing that works is setTimeout (but that's too hacky)

const handleActive = async (num, text) => {
await setDirection(text)
await setActive(num)
}
const handleActive = async (num, text) => {
await setDirection(text)
  setTimeout(() => {
    setActive(num)
  }, 600);
}

How could I pause (and modify the DOM?) to update the classNames before running setActive()? Console.log and the source code show the correct classNames, but somehow not in time before setActive()...

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

This is a rough idea of using useEffect. You could also use num as a dependency if you need. Or you could use functions. My main point would be to put most if not all of the conditional logic inside of useEffect. (or at least be abstracted from useEffect)

useEffect(() => {
  if (direction === "to-left") {
    setActive(-1)
  } else {
   setActive(1)
  }
}, [direction]);
about 4 years ago · Juan Pablo Isaza Denunciar

0

I was able to solve the problem with a "placeholder variable" - activeSetter (the problem with the earlier useEffect solution was that it was not triggered if the direction didn't change). Now everything happens in the right order:

  • the right className is set on non-active cards
  • the activeSetter holds the number of the next active card
  • and changes in activeSetter triggers useEffect that sets the new active card
const [activeSetter, setActiveSetter] = useState(1)

  useEffect(() => {
    setActive(activeSetter)
  }, [setActive, activeSetter])
  

  const handleActive = (num, text) => {
    setDirection(text)
    setActiveSetter(num)
  }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda