5

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.

PCPbiscuit
  • 417
  • 5
  • 16

1 Answers1

2

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.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Giraphi
  • 1,383
  • 1
  • 11
  • 26
  • Looks pretty neat but I'm trying to do it without external libraries which are made specifically for it. It's not only about making it look elegant but also understanding how it works. However, your solutions is really cool, I shall try it out later – PCPbiscuit Aug 23 '21 at 14:47
  • If you want to use basic react only, I think your approach with a `mounted` state and the `useEffect` is correct. The only thing I'd do different is to reorganize the css. I.E. not using individual classes for everything but maybe one class `navbar` that holds all the 'normal' css and then add a class `is-mounted` once it's mounted (and that is-mounted class holds the translateX). But you'd probably need to share your css for us to say more about this. Where do those classes like `flex` etc. come from? – Giraphi Aug 23 '21 at 14:56
  • Those are tailwind's utility-first classes. And I agree with you about is-mounted, that's actually what I wanted to do but I decided to check here if there are any better ways of implementing this. Thanks a lot dude – PCPbiscuit Aug 23 '21 at 15:09