Home > database >  React prevent css animation restarting every state change
React prevent css animation restarting every state change

Time:09-10

I have two child components, an image gallery and a hidden components which will display the clicked image of the gallery at full size.

    const [selectedIndex, setSelectedtIndex] = useState(0);
    const [galleryVisible, setGalleryVisible] = useState(false);

    const FirstComponent = () => {
        return (
           <div className={'gallery-container'}>
               <div class='img fade-1' onClick={() => handleClick(1)}>Image 1</div>
               <div class='img fade-2' onClick={() => handleClick(2)}>Image 2</div>
               <div class='img fade-3' onClick={() => handleClick(3)}>Image 3</div>
               [...]
           </div>
        )
    }

    const handleClick = (index) => {
        setSelectedtIndex(index)
        setGalleryVisible(true)
    }

    const SecondComponent = ({ index }) => {
        return (
            <div className={`selected-img`}>Selected : {index} (But the fading animation shouldn't restart è_é)</div>
        )
    }

    return (
        <>
            <FirstComponent/>
            {galleryVisible && 
                <SecondComponent index={selectedIndex} />
            }
        </>
    )

The issue is that I also have a fade-in animation on the first component, and every time I click on an image to display the second component, that animation resets due to the rerender of react on state change.

    &.fade-1 {
      animation-delay: 0s
    }
    &.fade-2 {
      animation-delay: 0.5s
    }
     &.fade-3 {
      animation-delay: 1s
    }

I don't know how can I only change the second component when the state is changed from a click on the first one... I tried to play with useMemo but couldn't get it to work.

Here is a codepen reproducing the issue : https://codepen.io/disgallion/pen/zYjqPBE

CodePudding user response:

Move the first component outside of App and pass handleClick to its props:


  const FirstComponent = ({handleClick}) => {
    return (
      <div className={'gallery-container'}>
        <div class='img fade-1' onClick={() => handleClick(1)}>1</div>
        <div class='img fade-2' onClick={() => handleClick(2)}>2</div>
        <div class='img fade-3' onClick={() => handleClick(3)}>3</div>
      </div>
    )
  }

const App = () => {
  const [selectedIndex, setSelectedtIndex] = useState(0);
  const [galleryVisible, setGalleryVisible] = useState(false);

  const handleClick = (index) => {
    console.log('click')
    setSelectedtIndex(index)
    setGalleryVisible(true)
  }


  
  const SecondComponent = ({ index }) => {
    return (
      <div className={`selected-img`}>Selected : {index} (But the fading animation shouldn't restart è_é)</div>
    )
  }
  
  return (
    <>
      Click on an image to open the fullsize gallery:
      <FirstComponent handleClick={handleClick} />
      {galleryVisible && 
        <SecondComponent index={selectedIndex} />
      }
    </>
  )
}

ReactDOM.render(<App />,
document.getElementById("root"))

Now the state change of App will not trigger a re-render in FirstComponent

  • Related