PCPbiscuit
PCPbiscuit

Reputation: 593

React onMount animations

I'm trying to create an onMount animation using React (and Tailwind but it doesn't matter). My current implementation is this:

const Component = () => {
    const [mounted, setMounted] = useState(false)
    useEffect(() => {
        setTimeout(() => {
            setMounted(true)
        }, 250)
    }, [])

return(
    <nav
    className={classNames(
    'flex justify-between items-center transform-gpu transition-transform duration-500',
     mounted ? 'translate-x-0' : '-translate-x-full')}> Some nav components </nav>
)
  }

Basically, this code timeouts the state's change, which indicates when the component is mounted, and then applies CSS translate to the element.
I'm thinking about optimizing the current solution but was wondering if there are any other ways to do an onMount animations. I appreciate any advice. I can create a SandBox example if that's necessary.

Upvotes: 6

Views: 4587

Answers (2)

jan.grp
jan.grp

Reputation: 61

You can do so by using @keyframes. Here is a working example (note that this is using tailwindcss):

React component:

import React from 'react';

function TransitionComponent() {
  return (
    <div className="w-48 h-48 bg-blue-500 animate-slide-left">
      {/* Content */}
    </div>
  );
}

export default TransitionComponent;

Global stylesheet:

@keyframes slide-left {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}

.animate-slide-left {
  animation: slide-left 0.5s ease-in-out;
}

With this approach you have maxium control over your animations and you do not need to install any package.

If you're using tailwind css and when you are fine with adding another dependency, I can also recommend tailwindcss-animate. It is very simple to use and specifically designed for animations on mounting events. And it has only a size of 18 kB!

Upvotes: 1

Giraphi
Giraphi

Reputation: 1651

Not sure if this precisely answers your question, but I personally like to use framer-motion for stuff like this. For example, if you want to apply an animated translateX once the component is mounted you could do something like this:

import { motion } from "framer-motion";

function Component() {
  return (
    <motion.nav
      initial={{ translateX: 0 }}
      animate={{ translateX: 100 }}
      transition={{ ease: "easeOut", duration: 2 }}
    >
      Some components
    </motion.nav>
  );
}

See this codesandbox. (Click the refresh button within the codesandbox-browser to retrigger the animation or use the mount/unmount button)

So instead of <nav> just use <motion.nav> and specify the animation via the framer-motion props. You can still style that element with other classes as before if you need them in addition.

Note that an even shorter way of expressing that is using the x property, as shown here:

    <motion.nav
      animate={{ x: 100 }}
      transition={{ ease: "easeOut", duration: 2 }}
    >
      Some components
    </motion.nav>

You can control the animations directly as attributes or use Animate Presence to control an animation for the component when it is unmounted.

Upvotes: 3

Related Questions