React ve Gerçek Zamanlı Döviz API'si ile Döviz Dönüştürücü Nasıl Oluşturulur
React ile döviz dönüştürücü oluşturmak, API entegrasyonunu, React hook'larını ve gerçek dünya durum yönetimini pratik yapmak isteyen geliştiriciler için mükemmel bir projedir. Bu adım adım öğreticide, bir döviz API'sinden gerçek zamanlı döviz kurlarını getiren, 170'ten fazla para birimini destekleyen ve hataları zarif bir şekilde işleyen tam işlevli bir döviz dönüştürücü oluşturacaksınız — hepsi modern React kalıplarını kullanarak.
Döviz kurlarının nasıl çalıştığını öğrenmek istiyorsanız, başlamadan önce döviz kuru açıklayıcımıza göz atın.
Ne Oluşturacaksınız
Bu öğreticinin sonunda, şu özelliklere sahip bir React döviz dönüştürücünüz olacak:
- Finexly API'sinden gerçek zamanlı döviz kurlarını getirir
- Açılır menü aracılığıyla 170'ten fazla para birimini destekler
- Kullanıcı yazarken miktarları gerçek zamanlı olarak dönüştürür (debouncing ile)
- Yükleme durumlarını ve API hatalarını zarif bir şekilde işler
- Kuru ve son güncelleme zaman damgasını gösterir
Proje yapısı:
currency-converter/
├── src/
│ ├── components/
│ │ └── CurrencyConverter.tsx
│ ├── hooks/
│ │ └── useExchangeRate.ts
│ ├── App.tsx
│ └── main.tsx
├── package.json
└── vite.config.tsÖn Koşullar
Başlamadan önce şunlara sahip olduğunuzdan emin olun:
- Node.js 18+ yüklü
- React hook'ları (
useState,useEffect) hakkında temel bilgi - Ücretsiz Finexly API anahtarı (almak yaklaşık 30 saniye sürer)
Adım 1: React Projesini Kurma
Vite'ı derleme aracı olarak kullanacağız:
npm create vite@latest currency-converter -- --template react-ts
cd currency-converter
npm install
npm run devGeliştirme sunucunuz http://localhost:5173'te başlayacak.
Adım 2: Finexly API'sini Anlama
Finexly API, basit bir REST arayüzü aracılığıyla 170'ten fazla para birimi için gerçek zamanlı ve geçmiş döviz kurları sağlar:
GET https://finexly.com/api/v1/latest?base=USDTipik bir yanıt:
{
"base": "USD",
"date": "2026-04-07",
"rates": {
"EUR": 0.9182,
"GBP": 0.7871,
"JPY": 151.42
},
"timestamp": 1744012800
}Anahtarınızı istek başlığına ekleyin:
Authorization: Bearer API_ANAHTARINIZAylık 1.000 istek içeren ücretsiz plana kaydolabilirsiniz.
Adım 3: Özel Hook Oluşturma
src/hooks/useExchangeRate.ts dosyasını oluşturun:
import { useState, useEffect, useCallback } from "react";
interface ExchangeRateResult {
rates: Record<string, number> | null;
loading: boolean;
error: string | null;
lastUpdated: Date | null;
}
const API_KEY = import.meta.env.VITE_FINEXLY_API_KEY;
const BASE_URL = "https://finexly.com/api/v1";
const rateCache: Record<string, { rates: Record<string, number>; timestamp: number }> = {};
const CACHE_TTL_MS = 5 * 60 * 1000;
export function useExchangeRate(baseCurrency: string): ExchangeRateResult {
const [rates, setRates] = useState<Record<string, number> | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const fetchRates = useCallback(async (base: string) => {
const cached = rateCache[base];
if (cached && Date.now() - cached.timestamp < CACHE_TTL_MS) {
setRates(cached.rates);
setLastUpdated(new Date(cached.timestamp));
return;
}
setLoading(true);
setError(null);
try {
const res = await fetch(`${BASE_URL}/latest?base=${base}`, {
headers: { Authorization: `Bearer ${API_KEY}` },
});
if (!res.ok) throw new Error(`API hatası: ${res.status} ${res.statusText}`);
const data = await res.json();
rateCache[base] = { rates: data.rates, timestamp: Date.now() };
setRates(data.rates);
setLastUpdated(new Date());
} catch (err) {
setError(err instanceof Error ? err.message : "Döviz kurları alınamadı");
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
if (baseCurrency) fetchRates(baseCurrency);
}, [baseCurrency, fetchRates]);
return { rates, loading, error, lastUpdated };
}Adım 4: CurrencyConverter Bileşenini Oluşturma
src/components/CurrencyConverter.tsx oluşturun:
import { useState, useMemo } from "react";
import { useExchangeRate } from "../hooks/useExchangeRate";
const CURRENCIES = [
"USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF", "CNY",
"INR", "MXN", "BRL", "KRW", "SGD", "HKD", "NOK", "SEK",
];
export default function CurrencyConverter() {
const [amount, setAmount] = useState<string>("100");
const [baseCurrency, setBaseCurrency] = useState<string>("USD");
const [targetCurrency, setTargetCurrency] = useState<string>("EUR");
const { rates, loading, error, lastUpdated } = useExchangeRate(baseCurrency);
const convertedAmount = useMemo(() => {
if (!rates || !amount) return null;
const numAmount = parseFloat(amount);
if (isNaN(numAmount) || numAmount < 0) return null;
const rate = rates[targetCurrency];
return rate ? (numAmount * rate).toFixed(2) : null;
}, [rates, amount, targetCurrency]);
const handleSwap = () => {
setBaseCurrency(targetCurrency);
setTargetCurrency(baseCurrency);
};
return (
<div className="converter-card">
<h2>Gerçek Zamanlı Döviz Dönüştürücü</h2>
<div className="input-row">
<label htmlFor="amount">Miktar</label>
<input
id="amount"
type="number"
min="0"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Miktarı girin"
/>
</div>
<div className="currency-row">
<div className="select-group">
<label htmlFor="base">Kaynak</label>
<select id="base" value={baseCurrency} onChange={(e) => setBaseCurrency(e.target.value)}>
{CURRENCIES.map((c) => <option key={c} value={c}>{c}</option>)}
</select>
</div>
<button className="swap-btn" onClick={handleSwap} aria-label="Para birimlerini değiştir">⇄</button>
<div className="select-group">
<label htmlFor="target">Hedef</label>
<select id="target" value={targetCurrency} onChange={(e) => setTargetCurrency(e.target.value)}>
{CURRENCIES.map((c) => <option key={c} value={c}>{c}</option>)}
</select>
</div>
</div>
<div className="result-area">
{loading && <p>En güncel kurlar alınıyor...</p>}
{error && <p className="error-text">⚠ {error}</p>}
{!loading && !error && convertedAmount !== null && (
<>
<p className="converted-value">
{parseFloat(amount).toLocaleString()} {baseCurrency} =
<strong>{parseFloat(convertedAmount).toLocaleString()} {targetCurrency}</strong>
</p>
{lastUpdated && <p>Kurlar güncellendi: {lastUpdated.toLocaleTimeString()}</p>}
</>
)}
</div>
</div>
);
}Adım 5: Ortam Değişkenleri
Proje kökünde bir .env dosyası oluşturun:
VITE_FINEXLY_API_KEY=api_anahtarınız_burayaAPI anahtarınızı korumak için .env'yi .gitignore'a ekleyin.
Adım 6: Uygulamayı Bağlama
src/App.tsx'i güncelleyin:
import CurrencyConverter from "./components/CurrencyConverter";
function App() {
return (
<main>
<CurrencyConverter />
<footer>
<p>Döviz kurları <a href="https://finexly.com">Finexly</a> tarafından sağlanmaktadır</p>
</footer>
</main>
);
}
export default App;Daha İleri Gitmek
Yüksek değerli iyileştirmeler şunları içerir: Finexly geçmiş API'si aracılığıyla geçmiş kur grafiği, eş zamanlı çoklu döviz dönüşümü, localStorage'da kaydedilen favori döviz çiftleri ve Next.js ile sunucu taraflı render.
Sıkça Sorulan Sorular
React için en iyi döviz kuru API'si hangisidir? React uygulamaları için CORS'u destekleyen bir REST API'ye ihtiyacınız var. Finexly API, tüm planlarda CORS'u destekler ve ücretsiz katmanla 170'ten fazla para birimi sunar.
Döviz kurları ne sıklıkla güncellenir? Finexly API, gerçek zamanlı planlar için her 60 saniyede ve standart planlar için günde bir kez günceller.
Bir istemci taraflı React uygulamasında döviz API'si kullanabilir miyim? API CORS'u destekliyorsa evet. Prodüksiyon uygulamaları için, istekleri kendi arka ucunuz aracılığıyla yönlendirmek en iyi uygulamadır.
React'ta API anahtarımı nasıl ifşa etmemem gerekir?
Geliştirme için, VITE_ önekiyle Vite'ın .env dosyasını kullanın. Prodüksiyon için, istekleri bir Next.js API Route veya serverless işlevi aracılığıyla yönlendirin.
USD olmayan iki para birimi arasında nasıl dönüştürebilirim? Finexly API, tüm planlarda herhangi bir temel para birimini destekler ve bu işlemi büyük ölçüde basitleştirir.
React uygulamanıza gerçek zamanlı döviz kurları eklemeye hazır mısınız? Ücretsiz Finexly API anahtarınızı alın — kredi kartı gerekmez. Ayda 1.000 ücretsiz istekle başlayın ve büyüdükçe yükseltin.
Explore More
Vlado Grigirov
Senior Currency Markets Analyst & Financial Strategist
Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...
View full profile →