I am trying to make a skeleton loading effect when isLoading state is true (its set to true on init), like this =>
{isLoading ? (
<div className="grid grid-cols-4 gap-3">
{voiceData.voices.map((voice) => (
<Skeleton key={voice.voice_id} className="w-[200px] h-[250px] rounded-md" />
))}
</div>
) : <div id="dash-card-container" className="grid grid-cols-4 gap-3" >
{voiceData.voices.map((voice) => (
<VoiceCard onClick={() => {
// Store the voice object in localStorage
localStorage.setItem("voice", JSON.stringify(voice));
console.log(localStorage.getItem("voice"));
// Navigate to the editor route
navigate("/create/editor");
}} key={voice.voice_id} img={voice.img} name={voice.name} category={voice.category} />
))}
</div>
}
But for some reason it’s not working when I reload the page, here is my useEffect for calling the api
// Fetching voices from api
useEffect(() => {
const fetchVoices = async () => {
// async function to fetch voices
try {
setIsLoading(true);
const response = await axios.get("http://localhost:3000/voices");
const data = response.data;
console.log("data:", data);
setVoiceData(data);
console.log("Voicedata fetched:", voiceData)
} catch (error) {
console.error("Error fetching voices", error)
setIsLoading(false)
} finally {
setIsLoading(false);
}
};
fetchVoices();
}, []);
I’ve tried to removing the "finally" block but this did not do it either
useEffect(() => {
const fetchVoices = async () => {
// async function to fetch voices
try {
setIsLoading(true);
const response = await axios.get("http://localhost:3000/voices");
const data = response.data;
console.log("data:", data);
setVoiceData(data);
console.log("Voicedata fetched:", voiceData)
setIsLoading(false)
} catch (error) {
console.error("Error fetching voices", error)
setIsLoading(false)
}
};
fetchVoices();
}, []);
I know my loading effect is working because if I never set setIsLoading => false it shows up.
I’ve also tried console.logging both at the beginning of the try block where I set it to true and at the end where I set it to false and it’s the same value every time, either true or false, but this has no impact on rendering which I find weird.
I’m a bit new to this but I don’t think I have missed anything major. Any help would be greatly appriciated as I’ve banged my head for a while now.
2
Answers
You can move
fetchVoices
outside of theuseEffect
. Also, check to see if your API request was successful before mutatingisLoading
as so:The problem is that you are setting isLoading to true before making the API call and immediately setting it to false in the finally block, which means that it might be set to false before the API call is completed.
You can set isLoading to false in the finally block only if the API call is successful.