When making changes to the className in CSS transitions may lag a step behind

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...

Answer №1

Here is a basic example of implementing the useEffect hook in React. You can also include 'num' as a dependency if needed, or use functions instead. The key idea is to encapsulate most, if not all, conditional logic within the useEffect function (or at least separate it from there).

useEffect(() => {
  if (direction === "to-left") {
    setActive(-1)
  } else {
   setActive(1)
  }
}, [direction]);

Answer №2

After encountering a challenge, I found a solution using a unique method known as a "placeholder variable" called activeSetter. This approach addressed the issue with the previous useEffect solution, ensuring it triggered even when the direction remained unchanged. As a result, the following sequence now unfolds seamlessly:

  • Correct classNames are applied to non-active cards.
  • The activeSetter retains the next active card's number.
  • Updates to activeSetter prompt the useEffect function to designate the new active card.
const [activeSetter, setActiveSetter] = useState(1)

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

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the process for setting dynamic variables as CSS content within Vue.js?

Forgive my lack of expertise, but I am interested in learning more about utilizing dynamic variables and CSS within Vue. I have a concept in mind where pressing a button would result in the letters of the button label spacing out further. Is it feasible t ...

Choosing the state object name dynamically within a React JS component

I have a quick question about updating state in React. How can I change a specific object in a copy of the state that is selected using e.target.name and then set to e.target.value? For example, if I want to change newState.age when e.target.name = age i ...

CSS Stylelint rule to detect the 'missing selector' issue

My current process involves using stylelint to identify any CSS errors before building and deploying our site. However, a recent commit includes code that fails the CSS parser/minifier but passes stylelint validation. .example-class , /*.example-class-two ...

Attempting to bring in HTML through a helper, but Rails doesn't seem too thrilled about it

I have a form that triggers a remote GET request, leading to the display of a modal. The issue I'm facing is that multiple actions can utilize the same model, so I am attempting to employ a helper and jQuery to showcase different data based on what is ...

Utilizing sip.js and websockets for registration in Node with the option of using wss or ws

I am currently working on registering SIP agents using sip.js and Node for conducting load testing on my Kamailio server. Node version v0.10.32 process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" global.WebSocket = require('ws') // SipJS Initializat ...

What is the best way to enhance the appearance of a list item that includes a visited hyperlink?

Currently, I am utilizing Stylebot in Chrome to modify certain styles on a webpage that I frequently browse. My goal is to conceal elements in a list that have links I have already visited. For instance, there is a <tr> with the class table-row, and ...

Comparing Dates in Node.js using JavaScript and Sorting Arrays based on Date Values

Is JavaScript lacking a basic Date comparison feature similar to Python? Within my Node.js script, these lines are present: console.log(Date(2012,11,10) < Date(2012, 11, 9)) console.log(Date(2012,11,10) > Date(2012, 11, 9)) Surprisingly, both of t ...

Run code from an inline script that is retrieved from an external origin

I am encountering an issue with my React app where I need to fetch index.html from one server location and run its scripts from another server location: const entries = await axios.get(`http://localhost:xxx`); let domParser = new DOMParser(); let tempDO ...

Retrieve information from an array of objects by utilizing a separate array

There are two separate arrays provided below: ages = [20,40,60]; doctors = [{ "name": "Moruu", "age": 18, "sex": "Male", "region": "Africa" }, { "name": "Khol ...

Leveraging Framer Motion's ScrollTrigger to Securely Pin and Unpin Elements while Scrolling

I recently started using Framer Motion and I'm attempting to replicate ScrollTrigger's feature of pinning and unpinning elements while scrolling. My current setup unpins the box when the <Two /> component comes into view, but there is a sli ...

"Can you tell me the method for obtaining an array within an Angular

Within the realm of PHP, there exist certain elements within an array: $this->data['messages']['ms'][] = 'Line1'; $this->data['messages']['ms'][] = 'Line2'; along with a method that return ...

Sending JSON objects as parameters to WebMethod

I've encountered various errors while passing parameters to my WebMethod. Below are my attempts and the corresponding errors: globalData is an array, mapping is an array that can be deserialized to List<Mapping>, selectedFund is an integer. C ...

Is it possible to combine a data type and a specific value when using PropTypes oneOf?

Can PropTypes.oneOf be used to ensure the presence of a specific type or string literal? For example: display: PropTypes.oneOf([PropTypes.bool, 'autohide']), Or does it interpret PropTypes.bool as whatever literal value it returns? I couldn&ap ...

Customizing vertex sizes in BufferGeometry for diverse shapes

Currently, I am working on creating a 2D scatterplot using three.js and I need to customize the sizes of the points. You can check out my progress here. I'm struggling with adjusting the sizes of the points based on the "radius" property and also addi ...

Exporting JSON data as an Excel file in AngularJS, including the option to customize the fonts used for the

Currently, I am working on a project where I need to convert JSON data to an Excel file using JavaScript in combination with AngularJS. So far, I have successfully converted the JSON data to CSV format. However, I faced issues with maintaining the font s ...

Updating the class of the "like" button icon using an AJAX form within the HTML view of a Ruby on Rails application

I'm facing an issue where my page isn't updating the icon after a successful Ajax function. Even though the data is posted to the database without any problems, the content doesn't refresh unless I manually reload the page. I want to be able ...

What is the best way to pass multiple variables to a PHP file with AJAX using a GET request?

Can you help me figure out how to send both an I.D. value and a name value to a php file using ajax? Currently, I am successfully sending just the I.D. variable, however, when I attempt to add the name variable, the function stops working. The code that w ...

The dropdown menu vanishes from sight as soon as the cursor moves away from a link

Recently, I encountered an issue while trying to create a dropdown menu using Jquery. The problem arose when attempting to select the second link, as the entire menu would disappear. Additionally, is there a way to ensure that only one dropdown menu is vis ...

How is the server architecture typically designed in a node.js application?

Currently, I am developing a node.js application using socket.io and I'm seeking advice on how to structure the folders properly. The files that I have in my project include: Server.js package.json Additionally, I have: Client.js Index.html Incl ...

Tips for effectively outputting compiled MUI end tags in JSX from a wrapper function

Having some trouble getting MUI JSX to work properly within a function. The compiler keeps giving me errors about the closing tags for certain elements. In particular, it's pointing out issues with the last '</Grid>' and '<br ...