skip to Main Content

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.enter image description here

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


  1. You can move fetchVoices outside of the useEffect. Also, check to see if your API request was successful before mutating isLoading as so:

    const fetchVoices = async () => {
          setIsLoading(true);
          // async function to fetch voices
          try {
            const response = await axios.get("http://localhost:3000/voices");
            const data = response.data;
    
            if(data) setIsLoading(false);
            console.log("data:", data);
            setVoiceData(data);
            
            console.log("Voicedata fetched:", voiceData)
          } catch (error) {
            console.error("Error fetching voices", error)
            setIsLoading(false)
          } 
        };
    
    useEffect(() => {
        fetchVoices();
      }, [fetchVoices]);
    
    
    Login or Signup to reply.
  2. 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.

    useEffect(() => {
      const fetchVoices = async () => {
        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);
        } finally {
          setIsLoading(false); // Move this line inside the finally block
        }
      };
    
      fetchVoices();
    }, []);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search