Reputation: 1771
I use a function component, so i have to use UseState to handle component states. I'm trying to show a spinner when loading data with axios :
import { Spinner } from 'react-bootstrap';
const MandatesPage = props => {
const [mandates, setMandates] = useState([]);
const [loading, setLoading] = useState(false); // to handle spinner hide show
useEffect(() => {
setLoading(true); // here loading is true
console.log(loading)
axios
.get(`${config.api}/mandates`)
.then(response => response.data["hydra:member"],setLoading(false)) // here loading is false
.then(data => setMandates(data))
.catch(error => console.log(error.response));
}, []);
...
if (loading) return
return (
<Spinner animation="border" variant="primary" />
);
}
return (
..... // return the other logic of my app
)
}
my problem is the spinner is not shown and i put console.log(loading) after setLoading(true) but i got false value.
Upvotes: 0
Views: 2723
Reputation: 1986
The problem is that you're trying a asynchronous operation in a synchronous way. You should be holding until your API response gets back, something more like this:
useEffect(() => {
async function fetchMyAPI() {
let url = 'http://something/';
let config = {};
const response = await myFetch(url);
console.log(response);
}
fetchMyAPI();
}, []);
Applying to your example:
useEffect(() => {
setLoading(true);
async function fetchOnAxios() {
const response = await axios.get(`${config.api}/mandates`)
// Down below inside this function
// you can set the loading based on the response
}
fetchOnAxios()
}, []);
I deeply recommend this article for further reading, it has examples and everything.
Upvotes: 1
Reputation: 8804
Of course loading
is still false, because the setting is async and will only be true on the next render.
For the next render, the loading spinner will be returned, since loading will be true than. If the axios calls needs short than 16 - 32ms, which is the normal frame for each render in react, the loading spinner will not be shown, because loading will already be set back to false.
Upvotes: 1