Reputation: 115
I'm fetching data from an API based on user input. I'd like to display the text "Loading.." while the data is being fetch.
My problem is that this "Loading.." is never displayed no matter how slow my internet is. Although I set isLoading
to be true before fetching data.
Additionally, I'm logging console.log("isLoading:", isLoading)
in the body. Why does it get refreshed every i input something BEFORE hitting submit button.
import { useState } from "react";
// example user: 0x147412d494731cbb91dbb5d7019464a536de04dc
function App() {
const [data, setData] = useState([]);
const [enteredWallet, setEnteredWallet] = useState("");
const [isLoading, setIsLoading] = useState(false);
const walletChangeHandler = (event) => {
setEnteredWallet(event.target.value);
};
const submittedHandler = (event) => {
event.preventDefault();
fetchNFTHandler(enteredWallet);
console.log("enteredWallet:", enteredWallet);
};
function fetchNFTHandler(owner) {
setIsLoading(true);
fetch(
`https://api.opensea.io/api/v1/assets?owner=${owner}&order_direction=desc&offset=0&limit=10`
)
.then((res) => {
return res.json();
})
.then((data) => {
const tranformedData = data.assets.map((element, index) => {
return {
title: element.name,
id: index,
};
});
setData(tranformedData);
});
setIsLoading(false);
}
return (
<div className="App">
<header className="App-header">
<h3>Show me assets in this wallet</h3>
<form onSubmit={submittedHandler}>
<input
placeholder="wallet address"
value={enteredWallet}
onChange={walletChangeHandler}
/>
<button>Submit</button>
</form>
<div>
{console.log("isLoading:", isLoading)}
{!isLoading &&
data.map((element) => <li key={element.id}>{element.title}</li>)}
{isLoading && <p>Loading..</p>}
</div>
</header>
</div>
);
}
export default App;
Upvotes: 0
Views: 960
Reputation: 49
The setIsLoading(false);
is outside of the then(...) part. This should do the trick:
function fetchNFTHandler(owner) {
setIsLoading(true);
fetch(
`https://api.opensea.io/api/v1/assets?owner=${owner}&order_direction=desc&offset=0&limit=10`
)
.then((res) => {
return res.json();
})
.then((data) => {
const tranformedData = data.assets.map((element, index) => {
return {
title: element.name,
id: index,
};
});
setData(tranformedData);
})
.finally(() => {
setIsLoading(false);
});
}
Make sure to place it into a finally(...) as otherwise the loading state won't be turned off when an error occures.
Upvotes: 1
Reputation: 2129
Because you call setLoading(false)
before your promise is resolved.
Do this instead:
function fetchNFTHandler(owner) {
setIsLoading(true);
fetch(
`https://api.opensea.io/api/v1/assets?owner=${owner}&order_direction=desc&offset=0&limit=10`
)
.then((res) => {
return res.json();
})
.then((data) => {
const tranformedData = data.assets.map((element, index) => {
return {
title: element.name,
id: index,
};
});
setData(tranformedData);
setIsLoading(false); // Move it here
});
}
Don't put your console.log-statement in the jsx btw, put it above the return statement.
Upvotes: 2