This tutorial describes how to create a simple currency exchange app in just about 100 lines of code using the Create React App boilerplate. To see it in action check out this . live demo 🛠️ Preparation First, create the react app. I call it "rates". $ yarn create react-app rates Run the command in your root $ yarn start Your web app will be available on http://localhost:3000 ⚓ Fetching the currencies rate For currency exchange data we will use free API on exchangeratesapi.io We will load the latest data of the currencies rates. Install the and libraries. It helps to easily fetch API. swr unfetch $ yarn add swr unfetch Create the fetcher function outside the App component React ; ; fetch ; API_URL = ; fetcher = path => { res = fetch(API_URL + path); json = res.json(); json; }; // src/App.js import from "react" import "./App.css" import from "unfetch" const "https://api.exchangeratesapi.io" const async const await const await return // function App... Add in App component to fetch data useSWR React ; ; fetch ; useSWR ; { { : currencies } = useSWR( , fetcher); ; } import from "react" import "./App.css" import from "unfetch" import from "swr" // API_URL = ... // const fetcher = ... ( ) function App const data "/latest?base=EUR" return Welcome to your Currency exchange app! < > div </ > div Now we have the currencies rates in variable. currencies.rates To see the JSON data of currencies rates you can open the API url directly into your browser: https://api.exchangeratesapi.io/latest?base=EUR The query is used to get all rates relative to EUR currency. ?base=EUR 💄 Add the UI For ui, we will use the design system. Install it: material-ui $ yarn add @material-ui/core Create the UI for our currency exchange app in the component. App // ... import { Container, Paper, Grid, TextField, Select, MenuItem } from "@material-ui/core"; // ... function App() { const { data: currencies } = useSWR("/latest?base=EUR", fetcher); if (!currencies) { return null; } return ( Currency exchange EUR {Object.keys(currencies.rates).map((rate, key) => ( {rate} ))} EUR {Object.keys(currencies.rates).map((rate, key) => ( {rate} ))} ); } < = > Container className "currency-exchange-container" fixed < > h1 </ > h1 < = = = > Paper className "currency-exchange-paper" variant "outlined" elavation {1} < = > Grid container spacing {3} < = > Grid item xs {6} < = /> TextField type "number" </ > Grid < = > Grid item xs {6} < = /> TextField type "number" </ > Grid < = > Grid item xs {6} < > Select < = " "}> MenuItem value { EUR </ > MenuItem < = = > MenuItem key {key} value {rate} </ > MenuItem </ > Select </ > Grid < = > Grid item xs {6} < > Select < = " "}> MenuItem value { EUR </ > MenuItem < = = > MenuItem key {key} value {rate} </ > MenuItem </ > Select </ > Grid </ > Grid </ > Paper </ > Container Now, look at the following code snippet. We create the currency selection box by iterating over all possible rates from our API data. Since we fetch rates relative to EUR, so we should manually add the EUR item, because it doesn't exist in rates object. <Select> { .keys(currencies.rates).map( ( ))} < EUR < = " "}> MenuItem value { EUR </ > MenuItem Object ( ) => rate, key {rate} < = = > MenuItem key {key} value {rate} </ > MenuItem /Select> When the currencies are not loaded, we just return null, because of currencies rates is undefined at that moment. (!currencies) { ; } if return null Add some styles to App.css { : ; : ; : ; } { : flex; : column; : center; : center; : ; } { : ; : ; } { : ; } h1 font-weight 300 color #636363 margin-bottom 3rem .currency-exchange-container display flex-direction align-items justify-content height 100vh .currency-exchange-paper max-width 350px padding 30px 30px 40px 30px .MuiInput-root width 100% ⚙️ Add logic Now we add the inputs state to our component App { { : currencies } = useSWR( , fetcher); [fromValue, setFromValue] = useState( ); [toValue, setToValue] = useState( ); [fromCurrency, setFromCurrency] = useState( ); [toCurrency, setToCurrency] = useState( ); handleFromCurrencyChange = { setFromCurrency(e.target.value); }; handleToCurrencyChange = { setToCurrency(e.target.value); }; handleFromValueChange = { setFromValue( (e.target.value)); }; handleToValueChange = { setToValue( (e.target.value)); }; (!currencies) { ; } ( <h1>Currency exchange</h1> <Paper className="currency-exchange-paper" variant="outlined" elavation={1} > <Grid container spacing={3}> <Grid item xs={6}> <TextField type="number" value={fromValue} onChange={handleFromValueChange} /> </Grid> <Grid item xs={6}> <TextField type="number" value={toValue} onChange={handleToValueChange} /> </Grid> <Grid item xs={6}> <Select value={fromCurrency} onChange={handleFromCurrencyChange}> <MenuItem value={"EUR"}>EUR</MenuItem> {Object.keys(currencies.rates).map((rate, key) => ( <MenuItem key={key} value={rate}> {rate} </MenuItem> ))} </Select> </Grid> <Grid item xs={6}> <Select value={toCurrency} onChange={handleToCurrencyChange}> <MenuItem value={"EUR"}>EUR</MenuItem> {Object.keys(currencies.rates).map((rate, key) => ( <MenuItem key={key} value={rate}> {rate} </MenuItem> ))} </Select> </Grid> </Grid> </Paper> </Container> ); } ( ) function App const data "/latest?base=EUR" const 1 const 1 const "EUR" const "EUR" const => e const => e const => e parseFloat const => e parseFloat if return null return < = > Container className "currency-exchange-container" fixed Also, add the two following functions for currency exchange convertFromTo = { fromRate = fromCurrency === ? : currencies.rates[fromCurrency]; valueInEur = fromValue / fromRate; toRate = toCurrency === ? : currencies.rates[toCurrency]; setToValue(valueInEur * toRate); }; convertToFrom = { toRate = toCurrency === ? : currencies.rates[toCurrency]; valueInEur = toValue / toRate; fromRate = fromCurrency === ? : currencies.rates[fromCurrency]; setFromValue(valueInEur * fromRate); }; const => () const "EUR" 1 const const "EUR" 1 const => () const "EUR" 1 const const "EUR" 1 One function converts currencies forward, and other - backward. In both functions, firstly, we convert currencies to EUR, because all rates we fetched from API are relative to euros. The last thing is to add the React hooks which run the rates exchange after the input change. useEffect( { convertFromTo(); }, [fromValue, toCurrency]); useEffect( { convertToFrom(); }, [toValue, fromCurrency]); => () => () Here is a full file App.js React, { useState, useEffect } ; ; fetch ; useSWR ; { Container, Paper, Grid, TextField, Select, MenuItem } ; API_URL = ; fetcher = path => { res = fetch(API_URL + path); json = res.json(); json; }; { { : currencies } = useSWR( , fetcher); [fromValue, setFromValue] = useState( ); [toValue, setToValue] = useState( ); [fromCurrency, setFromCurrency] = useState( ); [toCurrency, setToCurrency] = useState( ); handleFromCurrencyChange = { setFromCurrency(e.target.value); }; handleToCurrencyChange = { setToCurrency(e.target.value); }; handleFromValueChange = { setFromValue( (e.target.value)); }; handleToValueChange = { setToValue( (e.target.value)); }; convertFromTo = { fromRate = fromCurrency === ? : currencies.rates[fromCurrency]; valueInEur = fromValue / fromRate; toRate = toCurrency === ? : currencies.rates[toCurrency]; setToValue(valueInEur * toRate); }; convertToFrom = { toRate = toCurrency === ? : currencies.rates[toCurrency]; valueInEur = toValue / toRate; fromRate = fromCurrency === ? : currencies.rates[fromCurrency]; setFromValue(valueInEur * fromRate); }; useEffect( { convertFromTo(); }, [fromValue, toCurrency]); useEffect( { convertToFrom(); }, [toValue, fromCurrency]); (!currencies) { ; } ( <h1>Currency exchange</h1> <Paper className="currency-exchange-paper" variant="outlined" elavation={1} > <Grid container spacing={3}> <Grid item xs={6}> <TextField type="number" value={fromValue} onChange={handleFromValueChange} /> </Grid> <Grid item xs={6}> <TextField type="number" value={toValue} onChange={handleToValueChange} /> </Grid> <Grid item xs={6}> <Select value={fromCurrency} onChange={handleFromCurrencyChange}> <MenuItem value={"EUR"}>EUR</MenuItem> {Object.keys(currencies.rates).map((rate, key) => ( <MenuItem key={key} value={rate}> {rate} </MenuItem> ))} </Select> </Grid> <Grid item xs={6}> <Select value={toCurrency} onChange={handleToCurrencyChange}> <MenuItem value={"EUR"}>EUR</MenuItem> {Object.keys(currencies.rates).map((rate, key) => ( <MenuItem key={key} value={rate}> {rate} </MenuItem> ))} </Select> </Grid> </Grid> </Paper> </Container> ); } export default App; import from "react" import "./App.css" import from "unfetch" import from "swr" import from "@material-ui/core" const "https://api.exchangeratesapi.io" const async const await const await return ( ) function App const data "/latest?base=EUR" const 1 const 1 const "EUR" const "EUR" const => e const => e const => e parseFloat const => e parseFloat const => () const "EUR" 1 const const "EUR" 1 const => () const "EUR" 1 const const "EUR" 1 => () => () if return null return < = > Container className "currency-exchange-container" fixed ✨ Finished! Congratulations! You have done the currency exchange app using the CRA (Create React App). The full source code you can find in my repository . epranka/rates . Live demo Thanks for reading this. I hope it was helpful to you. Feedback and questions are appreciated. Follow on , , and let’s connect on Twitter GitHub LinkedIn (Originally published ) here