skip to Main Content

I’ve created a currency converter app with next.js. It works fine. However I also try to insert a functionality that allows users to swap From and To currencies back and forth.

This is the function code:

 const swapCurrencies = () => {
   console.log("Before Swap:", convertFrom, convertTo);
   setConvertFrom(convertTo);
   setConvertTo(convertFrom);
   console.log("After Swap:", convertFrom, convertTo);
 };

This is the button:

  <button onClick={swapCurrencies}>
    Swap
  </button>

These are input fields for From and To currencies:

    <Input
      label="From:"
      dropdown={true}
      onChange={setConvertFrom}
      symbols={symbols}
    />
    <Input
      label="To:"
      dropdown={true}
      onChange={setConvertTo}
      symbols={symbols}
    />

Related snippet of input.js file:

    {(dropdown && (
      // Dropdown list for From & To currencies
      <select name="countries" onChange={(e) => onChange(e.target.value)} className="px-4 py-2 rounded-xl">
      {arrOfSymbols.map((symbol) => (
        <option value={symbol} key={arrOfSymbols.indexOf(symbol)}>
          {symbols[symbol]}
        </option>
      ))}

When I click on the Swap button, it doesn’t work. I’ve inspected on the console and found out that the function is getting called but the values are not getting swapped.

From the console:

Before Swap: USD EUR
After Swap: USD EUR

Can anyone advice me on what should I try to make this function work?

2

Answers


  1. The useState hook is not synchronous. You cannot print the console log just after the setState and get the updated value because it was not updated yet.

    However, you can use the useState function assignment like this and put the console log inside the function, there you will see the value just before the change:

    setConvertFrom( 
        (prevState) => { 
            console.log("setting convertForm state:", convertTo)
            return convertTo
        }
    );
    

    and, you can use the useEffect hook in order to listen to the state after the change

    useEffect(() => {
        console.log("After Swap:", convertFrom, convertTo);
    }, [convertFrom, convertTo])
    
    Login or Signup to reply.
  2. If you are worry about the visual change or render or the both Input, You have to provide a key props to each of the Input Components.

    <Input
      key={convertFrom}
      label="From:"
      dropdown={true}
      onChange={setConvertFrom}
      symbols={symbols}
    />
    <Input
      key={convertTo}
      label="To:"
      dropdown={true}
      onChange={setConvertTo}
      symbols={symbols}
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search