Home > Mobile >  Can I use my own image as a React Loading icon/img
Can I use my own image as a React Loading icon/img

Time:01-06

We all know what a loading icon is, in React, I am wanting to replace that icon with an image/gif I have created. I have used npm i react-loading as the package, however, as this is my first time with this package, I am unsuccessful in having my images display at all. Im not entirely sure if this is due to a pathing error, or something else.

The intentions of this loader was to display this gif while the DOM is rendering, however, since I created the gifs myself, I love them so much I want to force other people to watch the gif in it's entirety before continuing. I have set a 5 second timeout on it, but not exactly sure if that was the right move. Maybe having a ternary would have been a simpler way to accomplish this.

Below is the Loading component I have set:

import {useState, useEffect} from 'react'
import Loading from 'react-loading'

const loadingGifsList = [
    '../loading-images/l1.gif',
    '../loading-images/l2.gif',
    '../loading-images/l3.gif',
    '../loading-images/l4.gif',
    '../loading-images/l5.gif',
    '../loading-images/l6.gif',
    '../loading-images/l7.gif',
    '../loading-images/l8.gif',
    '../loading-images/l9.gif',
    '../loading-images/l10.gif',
    '../loading-images/l11.gif',
    '../loading-images/l12.gif',
    '../loading-images/l13.gif'
]

const LoadingPage = () => {
    const [isLoading, setIsLoading] = useState(true)
    const loadingGif = loadingGifsList[Math.floor(Math.random() * loadingGifsList.length)]

    useEffect(() => {
        const timeout = setTimeout(() => {
            setIsLoading(false)
        }, 5000);
        
        return () => clearTimeout(timeout)
    }, [])
    
    if (isLoading) {
        return (
            <>
                <div>
                    <Loading src={loadingGif} />
                </div>
            </>
        )
    }
}

export default LoadingPage

I have an array of gifs, and one will be randomly selected.

Below is my App.js:

import axios from 'axios'
import { useState, useEffect } from 'react'
import Header from './components/Header.js'
import Add from './components/Add.js'
import Rules from './components/Rules.js'
import Select from './components/SelectGame'
import Player from './components/PlayerSelect.js'
import Board1 from './components/Player1_Board'
import Board2 from './components/Player2_Board'
import 'bootstrap/dist/css/bootstrap.min.css';
// import LoadingPage from './components/Loading.js'

// import css
import IndexCSS from './index.module.css';
import LoadingPage from './components/Loading.js'

const App = () => {
  // API data
  let [games, setGames] = useState([])
  // show/hides Add.js
  let [showAdd, setAdd] = useState(false)
  // show/hides Rules.js
  let [showRules, setRules] = useState(true)
  // show/hides SelectGame.js
  let [showSelect, setSelect] = useState(false)
    // show/hides the PlayerSelect and Player1/Player2 board until choice is made on SelectGame.js
  let [currentGameID, setCurrentGameID] = useState('')
    // show/hides PlayerSelect.js page
  let [playerSelect, setPlayerSelect] = useState(true)
    // show/hides Player1_Board.js page
  let [showP1, setP1] = useState(false)
  // show/hides Player2_Board.js page
  let [showP2, setP2] = useState(false)
  //show/hides loading images
  const [isLoading, setIsLoading] = useState(true)

  //=========================================================================
  //DELETE GAME
  const handleDelete = (event) => {
    axios.delete('https://connect4back.herokuapp.com/api/connect4/'   event.id).then((response) => {
      getGames();
    })
  }

  //=========================================================================
  //EDIT GAME
  const handleUpdate = (game) => {
    axios.put('https://connect4back.herokuapp.com/api/connect4/'   game.id, game).then((response) => {
      getGames();
    })
  }

  //=========================================================================
  //Create new game with players
  const handleCreate = (add) => {
    axios.post('https://connect4back.herokuapp.com/api/connect4', add).then((response) => {
      getGames();
    })
  }
  //=========================================================================
  //collect from database
  const getGames = () => {
    axios.get('https://connect4back.herokuapp.com/api/connect4').then((response) =>
      setGames(response.data),
      // , (err) => 
      // console.log(err)
    )
  }
  //=========================================================================
  //useEffect to collect from database
  useEffect(() => {
    getGames();
  }, [])

  // ========================================================================
  // display page
  return (
    <>
    <div>
      <LoadingPage isLoading={isLoading} setIsLoading={setIsLoading} />
    </div>
    

    
    <div className={IndexCSS.appContainer}>
      {/* Header of app */}
      <Header setAdd={setAdd} setRules={setRules} setSelect={setSelect} setCurrentGameID={setCurrentGameID} setP1={setP1} setP2={setP2}/>
      <div key={games.id}>
        {/* Show/Hide Rules.js */}
        {
          showRules === true ? <Rules setRules={setRules}/> : null
        }
        {/* Show/Hide Add.js */}
        {
          showAdd === true ? <Add handleCreate={handleCreate} setAdd={setAdd} setSelect={setSelect}/> : null
        }
        {/* show/hide SelectGame.js */}
        {
          showSelect === true ? <Select games={games} setSelect={setSelect} setCurrentGameID={setCurrentGameID} setPlayerSelect={setPlayerSelect}/> : null
        }
        {

        }
        {/* render game based on game ID selected from SelectGame.js */}
        {games.map((game) => {
          if (game.id === currentGameID) {
            return (
              <div key={game.id}>
                {/* Have player select P1 or P2, then render page */}
                {
                  playerSelect === true ? <Player game={game} setP1={setP1} setP2={setP2} setSelect={setSelect} setPlayerSelect={setPlayerSelect}/>: null
                }
                {/* show P1 page if true, else null */}
                {
                  showP1 === true? <Board1 game1={game} handleDelete={handleDelete} handleUpdate={handleUpdate} /> : null
                }
                {/* show P1 page if true, else null */}
                {
                  showP2 === true? <Board2 game2={game} handleDelete={handleDelete} handleUpdate={handleUpdate} /> : null
                }
              </div>
            )
          } else {
            return null
          }
        })}
      </div>
    </div>
    </>
  )
}

export default App

What is this currently producing?

So currently, when the page is loading, I have four circles moving left to right, and the most right circle fades out as a "new" circle (far left) fades in. It looks like a loading icon if you ask me. Why is it in the top left corner and not the centre? I have no idea.

Summary

In react, I want to use my gif/img as my loading "icon." I also like this image to be the centre of the screen. Just like most loaders, I would also like this to be the only thing visible while the loading icon is showing, and when it ends, display what the DOM has rendered.

Below is an image of what I see in the top left corner of my screen: 4 dots in the top left corner

CodePudding user response:

You need to move the isLoading state outside of the loading component and instead into the App.js component. Then, you should conditionally render only the loading component when the app is loading (basically the code you have in your loading component right now, that should be moved to App.js). You should then change your loading component to always render the GIF (since its render is controlled by App.js)

CodePudding user response:

Is this the library that you are using? https://github.com/fakiolinho/react-loading/blob/master/lib/react-loading.jsx#L7

As far as I checked, the library does not support any custom loading image.

I would recommend you use the official React Suspense instead and of course you can do any custom loading image. https://17.reactjs.org/docs/concurrent-mode-suspense.html

  • Related