import React, { useEffect, useState } from 'react';
import { Spinner } from 'react-bootstrap';
import Country from '../Country/Country'
const Countries = () => {
const[countries,setCountries]=useState([])
const [isLoading,setLoading]=useState(true)
useEffect(()=>{
fetch('https://restcountries.com/v3.1/all')
.then(res=>res.json())
.then(data=>setCountries(data))
setLoading(false)
},[])
return (
<div className='container'>
<div className="row row-cols-lg-4 row-cols-md-2 row-cols-sm-1 row-cols-1 g-2 mt-3">
{
isLoading?<Spinner animation='border'/>:countries.map(country=><Country key={Math.random(1,10)} country={country} />)
}
</div>
</div>
);
};
export default Countries;
Spinner is working Outside { }.But when I am trying this->
{isLoading?<Spinner animation='border'/>:countries.map(country=><Country key={Math.random(1,10)} country={country} />)}.
It is not working.I want to say It did not show any spinner before data showing
CodePudding user response:
Try to disable spinner after response arrive:
useEffect(()=>{
fetch('https://restcountries.com/v3.1/all')
.then(res=>res.json())
.then(data=>{
setCountries(data)
setLoading(false)
})
I suggest you to use only countries state:
const[countries,setCountries]=useState(null)
....
!countries?<Spinner animation='border'/>:countries.map(....
},[])
CodePudding user response:
First, make setLoading false whenever it gets data:
useEffect(() => {
fetch("https://restcountries.com/v3.1/all")
.then((res) => res.json())
.then((data) => {
setCountries(data);
setLoading(false);
});
}, []);
Use a function to render countries for good practise:
const renderCountries = () => {
countries.map((country) => (
<Country key={Math.random(1, 10)} country={country} />
));
};
Finally, check isLoading then show spinner other invoke the function to show countries:
{isLoading ? <Spinner animation="border" /> : renderCountries()}
CodePudding user response:
You should be logging what isLoading
is right before the return. You should also put the state change in the final then
to confirm that there is data and it has finished being retrieved.
useEffect(()=>{
fetch('https://restcountries.com/v3.1/all')
.then(res=>{
if (!res.ok){
console.log(res)
} else {
res.json()
}
}).then(data=>{
setCountries(data)
setLoading(false) // here is the state change
})
})
CodePudding user response:
Promise is asynchronous, setLoading(false) wont wait for response. It will simply update state. Put setLoading when data receive.
.then(data=>{
setCountries(data)
setLoading(false)
})