2
votes

please , help me, i want ti add a class-animation for this section, when section will unMount... section is in Route component

import React, {useEffect, useState} from "react";
import {GridRow} from "./components";

export const Home = ({animClass}) => {

    const [anim, setAnim] = useState("")

    useEffect(() => {
        return () => {
            setAnim("animated-section-rotateSlideOut")
        }
    }, [anim])


  return <section data-id="home" className={`animated-section start-page ${animClass} ${anim}`}>

      <div className="section-content vcentered">

          <GridRow>
              
                  <div className="title-block">
                      <h2>Alex Smith</h2>
                      <div className="owl-carousel text-rotation">
                          <div className="item">
                              <div className="sp-subtitle">Web Designer</div>
                          </div>

                          <div className="item">
                              <div className="sp-subtitle">Frontend-developer</div>
                          </div>
                      </div>
                  </div>
              
          </GridRow>

      </div>
  </section>
}
1
What's the issue you're facing? "help me, i want ti add a class-animation for this section, when section will unMount" And why do you want to add a class when it will un-mount? - Siddharth
a new page opens with animation and the old one should also change with animation, sorry for bad english - Ерванд С-ян
wneh I change home page to about page, about page opens with animation, and home page should be closed with animation too... - Ерванд С-ян
You should checkout react-spring - Siddharth

1 Answers

1
votes

As mentioned above in the comments, there are 3rd party tools like react-spring, React Transition Group, and my personal favorite, Framer Motion, that are purpose-built for adding animations to React. Each of these has a fairly easy to use API for adding exit animations.

If you're keen to do this on your own to learn more about how animations work, or because you don't need the extra weight of an additional package, here's one approach you can take that I've found reliable and effective.

Your idea of using the return function during the effect's cleanup phase isn't the way to go here. That's because by the time the function has run, the conditions that would cause the component to be removed from the DOM will be satisfied, so the unmounting proceeds and your animation never has time to run.

Instead, you can do something different using two state variables. With two variables, you can use one to control when to run the animation and the other as the condition to signal that the element should be removed from the DOM.

Using the onAnimationEnd event we'll be able to set the variable for removing the element from the DOM only after the CSS animation is done being run.

DEMO:

Click any red square to apply the animation then remove the element from the grid.

function Example() {
  const [animateOut, setAnimateOut] = React.useState(false)
  const [isRemoved, setIsRemoved] = React.useState(false);
  
  if (isRemoved) return null

  return (
    <div
      className="example"
      onClick={() => setAnimateOut(true)}
      style={animateOut ? {animationName: 'slide-out'} : {}}
      onAnimationEnd={() => setIsRemoved(animateOut)}
    />
  )
}

function App() {
  return (
    <main>
      <Example />
      <Example />
      <Example />
      <Example />
      <Example />
    </main>
  )
}


ReactDOM.render(
  <App />,
  document.getElementById("root")
);
@keyframes slide-out {
  to {
    transform: translateX(-100%) rotate(50deg);
    opacity: 0;
  }
}

.example {
  animation-duration: .3s;
  animation-fill-mode: forwards;
  background-color: red;
  height: 20vh;
  width: 20vh;
}

main {
 display: grid;
 grid-template-columns: repeat(auto-fill, 20vh);
 grid-gap: 1rem;
}
<div id="root"></div>

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>