Home > database >  React page update
React page update

Time:11-21

I'm making a loader for my React application in the form of a pizza that loses a piece every second. enter image description here

When I refresh the page, my loader doesn't behave correctly. Images appear simultaneously.

enter image description here

Below is the code for my component:

import React, {useEffect, useState} from 'react';
import './Loader.css'
import pizza0 from '../../images/loader/pizza0.png'
import pizza1 from '../../images/loader/pizza1.png'
import pizza2 from '../../images/loader/pizza2.png'
import pizza3 from '../../images/loader/pizza3.png'
import pizza4 from '../../images/loader/pizza4.png'
import pizza5 from '../../images/loader/pizza5.png'

const Loader = () => {
    const [imageStatus, setImageStatus] = useState({zero: true, first: false, second: false, third: false, fourth: false, fifth: false})
    const [currentImage, setCurrentImage] = useState(0)

    useEffect(() => {
        setTimeout(() => action(), 1000);
        const newCurrentImage = currentImage === 5 ? 0 : currentImage   1
        setCurrentImage(newCurrentImage)
    }, [imageStatus])

    function action() {
        switch (currentImage) {
            case 0:
                setImageStatus({...imageStatus, zero: false, first: true})
                break;
            case 1:
                setImageStatus({...imageStatus, first: false, second: true})
                break;
            case 2:
                setImageStatus({...imageStatus, second: false, third: true})
                break;
            case 3:
                setImageStatus({...imageStatus, third: false, fourth: true})
                break;
            case 4:
                setImageStatus({...imageStatus, fourth: false, fifth: true})
                break;
            case 5:
                setImageStatus({...imageStatus, fifth: false, zero: true})
                break;
        }
    }

    function PizzaImg0() {
        return (
            <img src={pizza0} className={imageStatus.zero ? "pizza active" : "pizza"}/>
        );
    }

    function PizzaImg1() {
        return (
            <img src={pizza1} className={imageStatus.first ? "pizza active" : "pizza"}/>
        );
    }

    function PizzaImg2() {
        return (
            <img src={pizza2} className={imageStatus.second ? "pizza active" : "pizza"}/>
        );
    }

    function PizzaImg3() {
        return (
            <img src={pizza3} className={imageStatus.third ? "pizza active" : "pizza"}/>
        );
    }

    function PizzaImg4() {
        return (
            <img src={pizza4} className={imageStatus.fourth ? "pizza active" : "pizza"}/>
        );
    }

    function PizzaImg5() {
        return (
            <img src={pizza5} className={imageStatus.fifth ? "pizza active" : "pizza"}/>
        );
    }

    return (
        <div>
            <PizzaImg0/>
            <PizzaImg1/>
            <PizzaImg2/>
            <PizzaImg3/>
            <PizzaImg4/>
            <PizzaImg5/>
        </div>
    );
};

export default Loader;

And very simple css

.pizza {
    height: 120px;
    display: none;
}

.pizza.active {
    display: flex;
}

At the same time, if I switch to another tab or open an IDE and then return to the page, the loader works fine. What changes in terms of React when I leave and then return to the page? And what can I do to get rid of the problem?

CodePudding user response:

Trigger action method in a different useEffect when currentImage changed

useEffect(() => {
    const newCurrentImage = currentImage === 5 ? 0 : currentImage   1
    setCurrentImage(newCurrentImage)
}, [imageStatus])

useEffect(() => {
    setTimeout(() => action(), 1000); 
}, [currentImage])

CodePudding user response:

You don't need to repeat creating your image tags. You can store the srcs in a ref since it's not going to change and it's not going to affect the render and have state for the active src. Something like this:

import React, { useEffect, useState, useRef } from 'react'
import './Loader.css'
import pizza0 from '../../images/loader/pizza0.png'
import pizza1 from '../../images/loader/pizza1.png'
import pizza2 from '../../images/loader/pizza2.png'
import pizza3 from '../../images/loader/pizza3.png'
import pizza4 from '../../images/loader/pizza4.png'
import pizza5 from '../../images/loader/pizza5.png'

const Loader = () => {
  const imageSrcs = useRef([pizza0, pizza1, pizza2, pizza3, pizza4, pizza5])
  const [currentImage, setCurrentImage] = useState(0)

  useEffect(() => {
    const timeoutId = setTimeout(() => {
      setCurrentImage((prevValue) => (prevValue === 5 ? 0 : prevValue   1))
    }, 1000)

    return () => clearTimeout(timeoutId)
  }, [])

  return (
    <div>
      <img src={imageSrcs.current[currentImage]} className={'pizza active'} />
    </div>
  )
}

export default Loader

  • Related