Click here to play with it on codesandbox.
How can we refactor it toward cleaner code?
First thing is to define an enum with the possible states.
Then, we can refactor the places where a boolean is in use.
import React, { useState } from "react";
import "./styles.css";
function CurrencyExchangeRefactored() {
const STATES = {
IDLE: "idle",
LOADING: "loading",
COMPLETE: "complete",
ERROR: "error"
};
const [from, setFrom] = useState("");
const [to, setTo] = useState("");
const [status, setStatus] = useState({
state: STATES.IDLE,
data: null
});
async function fetchData() {
setStatus({
state: STATES.LOADING
});
const response = await fetch(
`https://api.exchangeratesapi.io/latest?base=${from}&symbols=${to}`
);
response.json().then((result) => {
response.ok
? setStatus({
state: STATES.LOADING.COMPLETE,
data: result.rates[to]
})
: setStatus({
state: STATES.LOADING.COMPLETE,
data: result.error
});
});
}
const handleSubmit = (evt) => {
evt.preventDefault();
fetchData();
};
if (status.state === STATES.LOADING) {
return <div>Loading...</div>;
}
return (
<form onSubmit={handleSubmit}>
<label>
Euro:
<input
type="text"
name="from"
value={from}
onChange={(e) => setFrom(e.target.value)}
/>
</label>
<label>
To:
<input
type="text"
name="to"
value={to}
onChange={(e) => setTo(e.target.value)}
/>
</label>
<input type="submit" value="Submit" />
{status.state === STATES.IDLE ? null : (
<h2>
{status.state === STATES.ERROR ? (
<span>Error: </span>
) : (
<span>Rate: </span>
)}
{status.data}
</h2>
)}
</form>
);
}
export default CurrencyExchangeRefactored;
Click here to play with it on codesandbox.
Following this approach, the component will become more readable and maintainable. Adding a new status to the component will also become easier.