Story: Building the Currency Converter App
1. The Beginning: The User Interaction in the UI
Imagine you’ve just opened the currency converter app. You see two sections: one where you can enter the amount you want to convert, and the other where the converted amount will appear. There are also two dropdowns, one for selecting the currency you are converting from (e.g., USD) and another for selecting the currency you want to convert to (e.g., INR).
To make everything work, we need to:
Capture the amount entered by the user.
Store the selected currencies (from and to).
Calculate the converted amount based on the rates.
These steps involve React components, state management, API fetching, and event handling.
2. Setting Up the State in App.jsx
(The Central Brain)
import { useState } from 'react';
import './App.css';
import { InputBox } from './components';
import useCurrencyInfo from './hooks/useCurrencyInfo';
// The `App` component is the main brain of our app
function App() {
const [amount, setAmount] = useState(0); // Amount user wants to convert
const [from, setFrom] = useState("usd"); // Currency user wants to convert from (USD by default)
const [to, setTo] = useState("inr"); // Currency user wants to convert to (INR by default)
const [convertAmount, setConvertAmount] = useState(0); // Converted amount
// This hook fetches the currency conversion data based on the "from" currency
const currencyInfo = useCurrencyInfo(from);
// Options are the keys of the currencyInfo object
const options = Object.keys(currencyInfo);
At the start, App.jsx
is the starting point. It holds the state values, which are like storage containers that hold important information for the app:
amount
: The amount you want to convert (e.g., 10 USD).from
: The currency you are converting from (USD by default).to
: The currency you are converting to (INR by default).convertAmount
: This will hold the converted amount after the calculation.
React’s useState
hook is used to store these values. Think of it like a memory bank where we store the user inputs and the results.
3. Fetching the Currency Data with useCurrencyInfo
(Gathering Data)
Next, we need to fetch the conversion rates from an external API. This is where the useCurrencyInfo
hook comes in.
import { useEffect, useState } from "react";
// Custom hook to fetch currency information
const useCurrencyInfo = (currency) => {
const [currencyData, setCurrencyData] = useState({});
useEffect(() => {
const fetchCurrencyData = async () => {
try {
const response = await fetch(`https://cdn.jsdelivr.net/gh/fawazahmed0/currency-api@1/latest/currencies/${currency}.json`);
const data = await response.json();
setCurrencyData(data[currency]);
} catch (error) {
console.error("Error fetching currency data:", error);
}
};
fetchCurrencyData();
}, [currency]); // This effect runs whenever the "currency" changes
return currencyData;
};
Here’s what happens:
useEffect
: This is like a listener that waits for thefrom
currency to change. If thefrom
currency changes (e.g., from USD to EUR), it will fetch the new conversion rates for the selected currency.fetchCurrencyData
: This is an asynchronous function that calls an API to get the current conversion rates for the selected currency.- For example, if the user selects USD, it fetches the exchange rates for USD in relation to other currencies, like INR, EUR, etc.
setCurrencyData
: Once the data is fetched, it's stored in thecurrencyData
state, which is returned by the hook.
This means that whenever the user selects a new "from" currency, the app will fetch the latest conversion rates.
4. Showing the Data: The InputBox
Component
The InputBox
component is where the magic happens. It lets the user enter the amount they want to convert and select the currency from a dropdown.
const InputBox = ({ label, amount, CurrencyOptions, onCurrencyChange, onAmountChange, selectCurremcy, amountDisable }) => {
return (
<div className="w-full">
<label className="block text-sm font-medium text-gray-700">{label}</label>
<input
type="number"
value={amount}
onChange={(e) => onAmountChange(e.target.value)} // Update the amount
className="w-full px-4 py-2 border rounded-md"
disabled={amountDisable} // Disable the input field for the converted amount
/>
<select
value={selectCurremcy} // Value for the selected currency
onChange={(e) => onCurrencyChange(e.target.value)} // Update the currency when the user selects a new one
className="w-full mt-2 px-4 py-2 border rounded-md"
>
{CurrencyOptions.map((currency) => (
<option key={currency} value={currency}>
{currency.toUpperCase()}
</option>
))}
</select>
</div>
);
};
Input Field: This lets the user type in the amount they want to convert. When the user types, the
onAmountChange
function is called, which updates theamount
state inApp.jsx
.Currency Dropdown: This lets the user select the currency (USD, INR, etc.) they are converting from or to. When the user selects a different currency, the
onCurrencyChange
function is called, which updates thefrom
orto
currency inApp.jsx
.
This component is reused for both the "From" and "To" currency sections. It displays the amount and allows users to select a currency.
5. The swap
Function: Swapping Currencies
One of the key features of your app is the swap function, which lets the user switch the "From" and "To" currencies.
const swap = () => {
setFrom(to); // Swap 'from' and 'to' currencies
setTo(from);
setConvertAmount(amount); // Set the converted amount to the original amount
setAmount(convertAmount); // Update the amount based on the converted value
};
When the user clicks the swap button, the
from
andto
currencies are swapped.It then updates the
amount
with the converted amount, so the user can see the new result in the swapped direction.
This is a simple, but useful feature to switch the direction of currency conversion without needing to re-enter the data.
6. The Conversion Logic
The most important part: calculating the converted amount. This happens when the user submits the form.
const convert = () => {
setConvertAmount(amount * currencyInfo[to]); // Multiply the amount by the exchange rate for the selected 'to' currency
};
When the user submits the form by clicking the Convert button, the
convert
function is triggered.How does the conversion happen? The app multiplies the entered
amount
by the conversion rate stored incurrencyInfo[to]
(whereto
is the selected currency).- For example, if the user enters 100 USD and selects INR as the target currency, it multiplies the amount (100) by the conversion rate from USD to INR (e.g., 83.0), and the converted amount will be 8300 INR.
This final result is stored in convertAmount
and displayed on the UI.
7. The Final UI (Rendering Everything)
Lastly, after all the calculations and updates, the app renders the results.
return (
<div className="w-full h-screen flex flex-wrap justify-center items-center bg-cover bg-no-repeat">
<div className="w-full max-w-md mx-auto border border-gray-60 rounded-lg p-5 backdrop-blur-sm bg-white/30">
<form onSubmit={(e) => { e.preventDefault(); convert(); }}>
<div className="w-full mb-1">
<InputBox
label="From"
amount={amount}
CurrencyOptions={options}
onCurrencyChange={(currency) => setFrom(currency)}
onAmountChange={(amount) => setAmount(amount)}
selectCurremcy={from}
/>
</div>
<button type="button" onClick={swap}>Swap</button>
<div className="w-full mt-1 mb-4">
<InputBox
label="To"
amount={convertAmount}
CurrencyOptions={options}
onCurrencyChange={(currency) => setTo(currency)}
selectCurremcy={to}
amountDisable={true}
/>
</div>
<button type="submit">Convert {from.toUpperCase()} to {to.toUpperCase()}</button>
</form>
</div>
</div>
);
Form Submission: When the user clicks the Convert button, the
convert()
function is triggered, which calculates the converted amount and updates the UI.Displaying Results: The converted amount is displayed in the "To" section, which is updated dynamically as the user makes changes.
Summary of the Data Flow
User enters amount and selects currencies in the UI. This triggers state updates via React's
useState
.useCurrencyInfo
fetches the latest conversion rates from the API.Conversion calculation happens based on the user's input and fetched conversion rates.
Results are displayed back in the UI for the user to see.