skip to Main Content

I have a react app that

  • Takes an array of GIF urls
  • Renders the first one of the array
  • Allows the user to click on "Next/Back" to navigate through the array and render the Next/Previous GIF.

Under the hood, when a user clicks "Next"/"Back", I update the state of the "current index", pass the new GIF URL to the component and wait for the new GIF to load.

However, my issue right now is that it takes some time to load the new GIF (which is fine) but between the moment the user click next/back and the moment the new gif renders, the old gif is still on the screen.

So for a few secs it feels like the user clicked next but nothing changed.

How can I create some sort of "Loading" intermediate screen between the moment the user clicks next and when the new GIF is actually ready to be rendered?

GifViewer

import React, { useState } from 'react';


function Gif({ url }) {
    console.log(url)
    return (
        <div >
            <img
                className='img-gif'
                src={url}
                alt="GIF"
            />
        </div>
    );
    }

export default Gif;

App

import { useState } from 'react'
import './App.css'
import Gif from './components/GifViewer'



function App() {

  
  const [data, setData] = useState([]);


  const [currentGifIndex, setCurrentGifIndex] = useState(0);


  
  const handleNext = () => {
    setCurrentGifIndex((currentIndex) =>
      currentIndex >= data.length - 1 ? 0 : currentIndex + 1
    );
  };

  const handlePrev = () => {
    setCurrentGifIndex((currentIndex) =>
      currentIndex === 0 ? data.length - 1 : currentIndex - 1
    );
  };


  return (
    <div className="App">
      
   
        <div className='main'>
          <div className="left-side">
            <Gif url={data[currentGifIndex]['render_url GIF (2x speed)']}/>
          </div>
          <div className="right-side">
        
            <button className="nav-back" onClick={handlePrev}>Back</button>
            <button className="nav-next" onClick={handleNext}>Next</button>

          </div>
        </div>
    </div>
  )
}

export default App


2

Answers


  1. recreate the img element when url is changed

    GifViewer

    import React, { useCallback } from "react";
    
    function Gif({ url }) {
      const Com = useCallback(
        ({ url }) => {
          return (
            <img
              src={url}
              alt="GIF"
              style={{
                position: "absolute",
                width: "100%",
                height: "100%"
              }}
            />
          );
        },
        [url]
      );
      return (
        <div
          style={{
            position: "relative",
            width: "300px",
            height: "300px",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            overflow: "hidden"
          }}
        >
          <span>loading...</span>
          <Com url={url} />
        </div>
      );
    }
    
    export default Gif;
    
    Login or Signup to reply.
  2. In the return statement of your app.js, i think you should do this.

        <div className="App">
          <div className='main'>
              <div className="left-side">
            //add a check for if data is ready
                   {!data ? <h1>Loading!!!</h1> : 
                <Gif url={data[currentGifIndex]['render_url GIF (2x speed)']}/>
              </div>
              <div className="right-side">
            
                <button className="nav-back" onClick={handlePrev}>Back</button>
                <button className="nav-next" onClick={handleNext}>Next</button>
    
              </div>
            </div>
        </div>
      )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search