Tips for ensuring synchronous state changes in React

I am working on a currency calculator using react.js

I am fetching the latest exchange rates and storing them in state using the getRates function:

 getRates(currencyShortcut){
     fetch('https://api.fixer.io/latest?base='+currencyShortcut)
       .then(response => response.json())
       .then(parsedJson => this.setState({currencyRates:parsedJson}))
       .catch(error => console.log('fetch error - ', error))   
 }

These rates are then used to calculate the amount for a given input value, which is displayed on the screen as shown below:

calculateCurrenciesValues(curr,userInput){
  let currency1val,currency2val;
  const rate = this.state.currencyRates.rates[this.state.currency2.shortcut];
  if(curr === 1){
    currency1val = userInput;
    currency2val = Math.round(rate*userInput*100)/100;
  }else{
    currency1val = Math.round(userInput/rate*100)/100;
    currency2val = userInput;
  }
  this.setState({
    currenciesValues:[currency1val,currency2val]
  })
}

The initial HTTP request is made within the componentWillMount method

componentWillMount(){
    this.getRates('USD');
}

If a user selects a different currency from the list, the state needs to be updated with new rates. Here is the handler for changing the currency:

  changeCurrency(currFlag,currShortcut,currSymbol){
    const selectedCurrency = {
      path:currFlag,
      shortcut:currShortcut,
      symbol:currSymbol
    };
    const {listOfCurrencies,currency1,currency2,currenciesValues,currencyRates} = this.state; 

    if(this.state.listOfCurrencies.displayFor === 1 ){
      this.getRates(currShortcut);
      this.setState({
        currency1:selectedCurrency
      })
      this.calculateCurrenciesValues(1,currenciesValues[0])
    }
    else{
      this.setState({
        currency2:selectedCurrency
      });
      this.calculateCurrenciesValues(2,currenciesValues[1])
    }

    this.setState({
      listOfCurrencies:{
        display:!listOfCurrencies.display
      }
    })
  }

After changing the currency, the calculation should ideally be done with the freshly acquired data. However, I am facing an issue where the calculation is not updating with the new rates after changing the currency.

Any suggestions on how to ensure that the calculation uses the most up-to-date exchange rates?

Answer №1

Consider saving only the exchange rates and user selections in the state.

Calculate values within your render method to ensure it updates whenever the state is modified.

Answer №2

If your calculateCurrenciesValues() function is producing incorrect results, the issue may be related to the order in which you are setting state and calling functions.

Here's how I would tackle it...

  • User inputs a value into the field
  • An onChange event occurs to update the state with the current input value
  • The user changes the currency selection
  • An event triggers the function to calculate a new value based on the current state representing the user input

It seems like there could be a problem with the sequence of events in your code. Double check that your state is updated before performing calculations based on the current user input. Hopefully, this will provide some clarity. If not, feel free to reach out for further assistance.

Answer №3

Make sure to complete your ajax request before calling a method. Here's a suggested approach:

fetchCurrencyRates(shortcut, callback){
     fetch('https://api.fixer.io/latest?base='+shortcut)
       .then(response => response.json())
       .then(parsedJson => this.setState({currencyRates:parsedJson}, function(){
           if(callback){callback();}
       })
       .catch(error => console.log('fetch error - ', error))   
 }

 if(this.state.listOfCurrencies.displayFor === 1 ){
  this.fetchCurrencyRates(shortcut, function(){
      this.setState({
        currency1:selectedCurrency
      }, function(){
        this.calculateCurrenciesValues(1,currenciesValues[0])
      })
  });
}

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

The jQuery dynamic fields vanish mysteriously after being validated

I am facing an issue with my jQuery and validation. Below is the code snippet causing the problem: var fielddd = 1; $(document).on('click', '.btn.add-field', function() { fielddd++; $('#newfield').append('< ...

JavaScript design not aligning

I'm currently attempting to find a pattern that includes the pipe (|) operator. Here is the code I've used to match the pattern: var format = /[ \\|]/; // This is the pattern for matching the pipe pattern if ("Near raghavendra temple ...

On Linux systems, Node.js in JavaScript interprets strings as objects only

I'm encountering an issue with my Discord.io bot. I am attempting to run it on a Linux server, but the Linux version of Node.js keeps treating the contents of a string as a separate object, leading to the following TypeError: TypeError: Object IT&apo ...

What is the process of integrating an HTML web component with an HTML file? Can I use innerHTML = foo("myfile.html") to achieve

Using HTML web components allows me to define their code using this method: this.innerHTML = `<h1></h1>`; However, I find it cumbersome as I do not have access to the Emmet Abbreviation feature which slows down my component creation process. ...

Why isn't v-model functioning properly in Vue?

In my current project involving an API, I encountered a problem. I utilized axios to fetch data from the API, which returned a JSON array. Each array item had a radio value that I appended to it. Despite attempting to use v-model to track changes in the ra ...

You are unable to reference a member within the embed in discord.js v13

I created a system for logging join and leave events in my server. However, I encountered an issue where the member is not mentioned when the bot sends the embed in the channel. Here is a snippet of my code: client.on('guildMemberAdd', guildMemb ...

The getStaticProps function in Next.js does not pass any data back to the pages

After setting up my hosted database, I encountered an issue with fetching data from it. Despite confirming that the database is running smoothly through the Swagger app, no data appears when called via API form. import React from 'react'; export ...

Using Python and Selenium to manipulate the webpage and execute JavaScript can help reconstruct the true HTML structure

I have a very basic Selenium code snippet that I am running: <input name="X" id="unique" value="" type="text"> <script> document.getElementById("unique").value="123"; </script> While I can retrieve the input value "123" using driv ...

Issues with JSON data not functioning properly when using file system in JavaScript

When attempting to parse a JSON file, I encountered some errors. The file is located in a directory within my JavaScript file, under the 'fs' in a folder named "recipes." Within this folder, there are 3 JSON files, each representing a separate ob ...

Click to reveal additional images once the "show more" button is pressed

Hey there! I'm currently working on implementing a feature where, upon clicking "show more", 3 images will be displayed. And if the user clicks again, another set of 3 images will appear, and so on. I seem to be facing some difficulties with the JavaS ...

developing authentication codes using javascript

Currently, I am working on developing a sign-up system that allows users to easily generate a random string with the click of a button. The generated string can then be shared with non-users who wish to sign up. The new user will need to enter their chose ...

Creating a minigame using JQuery (Javascript)

I am currently developing a collection of mini-games for my big project. The approach I've taken in creating this mini-game is similar to one I used previously. However, unlike my previous version which only had one PuzzleContainer, this new iteration ...

Can the lazy load script dependent on jQuery be utilized before the jquery.js script tag in the footer?

After receiving HTML from an AJAX callback, I noticed that there is a script tag for loading code that uses jQuery. However, I consistently encounter the error of jQuery being undefined. All scripts are connected before the closing </body> tag. Is ...

Enhance your security with Ember-simple-auth when using ember-cli-simple-auth-token

Currently, I am in the process of utilizing ember-simple-auth alongside ember-cli-simple-auth-token: "ember-cli-simple-auth-token": "^0.7.3", "ember-simple-auth": "1.0.1" Below are my configurations: ENV['simple-auth-token'] = { authoriz ...

Display the list items when the page first loads

I currently have this code snippet: <nav> <ul class="sel"> <li> <a href="#LINK1" data-title="A">A</a> </li> <li> <a href ...

The data retrieved from the API call is outdated

I am struggling with a weather web API that is only showing old data when called in the code. However, when I enter the API URL directly into the browser, it displays the most up-to-date information for the current city. Can anyone help me troubleshoot why ...

What is the best way to break down my node module into separate files?

I am currently in the process of organizing my node module functions by splitting them into separate files to accommodate numerous functions that need to be added. My objective is to call the main file's functions from files located within the lib di ...

Spinner displayed upon task completion

Currently, I am developing a project using Spring Boot. I would like to display a spinner on my page to indicate that a task involving heavy calculations is in progress. Even though the page may take up to 5 minutes to load, my spinner only appears for t ...

What's the best way to ensure a div's height and width are equal when implementing responsive design?

I am currently working on a responsive design and facing challenges in making div's height and width equal. Initially, I set the div's width as a percentage and height as auto, but this caused the divs to not display properly. To resolve this iss ...

Using i18next to alter language in a React app

Implementing the i18next translation system into my React app was a breeze thanks to a helpful guide I found. However, I'm facing an issue with changing the language manually. The guide covered the setup process perfectly, but lacked information on ho ...