Mike Alejandro
Mike Alejandro

Reputation: 483

Issue wtih exit property - framer motion

i'm trying to get an animation in react with framer motion, and everything works, but, the exit property doesn't do anything, i don't know if i'm doing something wrong or what's happening there, i'm still learning the librabry so, i'm kinda noob at it..

So, let me show the code

These are the two components that i want to animate with exit

<UserData>
        {login ? (
          <Login setLogin={setLogin} />
        ) : (
          <Register setLogin={setLogin} />
        )}
      </UserData>

This is the login part, if you click the button register, this form will dissapear, and register will appear

import React from "react";
import { AnimatePresence } from "framer-motion";

import {
  FormAuth,
  TitleAuth,
  TitleAuthImage,
  ContainInput,
  InputAuth,
  ContainSingleInput,
  ContainButtons,
  Button,
  ButtonSpan
} from "../website/AuthStyled";

import instagram from "../img/instagram.svg";

const Login = ({ setLogin }) => {
  const handleSubmit = e => {
    e.preventDefault();
  };

  // Framer motion animations

  const PopUp = {
    hidden: { x: 0, opacity: 0, scale: 0.6 },
    visible: {
      x: 0,
      opacity: 1,
      scale: 1,
      transition: { delay: 0.6, duration: 1 }
    }
  };

  return (
    <AnimatePresence>
      <FormAuth
        onSubmit={handleSubmit}
        variants={PopUp}
        exit={{ x: 500, opacity: 0, transition: { duration: 0.5 } }}
        initial="hidden"
        animate="visible"
      >
        <TitleAuth>
          <TitleAuthImage src={instagram} />
        </TitleAuth>

        <ContainInput>
          <ContainSingleInput top="2rem">
            <InputAuth
              name="email"
              type="email"
              placeholder="Email"
              maxLength="50"
            />
          </ContainSingleInput>
          <ContainSingleInput top="7rem">
            <InputAuth
              name="password"
              type="password"
              placeholder="Password"
              maxLength="50"
            />
          </ContainSingleInput>
        </ContainInput>

        <ContainButtons>
          <Button
            type="submit"
            Login
            whileHover={{ scale: 1.1 }}
            whileTap={{ scale: 0.85 }}
          >
            Login
          </Button>
          <ButtonSpan
            Register
            whileHover={{ scale: 1.1 }}
            whileTap={{ scale: 0.85 }}
            onClick={() => setLogin(false)}
          >
            Register
          </ButtonSpan>
        </ContainButtons>
      </FormAuth>
    </AnimatePresence>
  );
};

export default Login;

And this is the register, it's the same logic, if you click login, register will disappear and the other one will appear

import React from "react";
import { AnimatePresence } from "framer-motion";

import {
  FormAuth,
  TitleAuth,
  TitleAuthImage,
  ContainInput,
  InputAuth,
  ContainSingleInput,
  ContainButtons,
  Button,
  ButtonSpan
} from "../website/AuthStyled";

import instagram from "../img/instagram.svg";

const Register = ({ setLogin }) => {
  const handleSubmit = e => {
    e.preventDefault();
  };

  // Framer motion animations

  const PopUp = {
    hidden: { x: 0, opacity: 0, scale: 0.6 },
    visible: {
      x: 0,
      opacity: 1,
      scale: 1,
      transition: { delay: 0.6, duration: 1 }
    }
  };

  return (
    <AnimatePresence>
      <FormAuth
        onSubmit={handleSubmit}
        variants={PopUp}
        exit={{ x: 1000, opacity: 0, transition: { duration: 0.5 } }}
        initial="hidden"
        animate="visible"
      >
        <TitleAuth>
          <TitleAuthImage src={instagram} />
        </TitleAuth>

        <ContainInput>
          <ContainSingleInput top="0rem">
            <InputAuth
              name="name"
              type="name"
              placeholder="Name"
              maxLength="40"
            />
          </ContainSingleInput>
          <ContainSingleInput top="4rem">
            <InputAuth
              name="password"
              type="password"
              placeholder="Password"
              maxLength="50"
            />
          </ContainSingleInput>
          <ContainSingleInput top="4rem">
            <InputAuth
              name="confirmPassword"
              type="confirmPassword"
              placeholder="Confirm Password"
              maxLength="50"
            />
          </ContainSingleInput>
          <ContainSingleInput top="4rem">
            <InputAuth
              name="email"
              type="email"
              placeholder="Email"
              maxLength="50"
            />
          </ContainSingleInput>
        </ContainInput>

        <ContainButtons>
          <Button
            type="submit"
            Register
            whileHover={{ scale: 1.1 }}
            whileTap={{ scale: 0.85 }}
          >
            Register
          </Button>
          <ButtonSpan
            Login
            whileHover={{ scale: 1.1 }}
            whileTap={{ scale: 0.85 }}
            onClick={() => setLogin(true)}
          >
            Login
          </ButtonSpan>
        </ContainButtons>
      </FormAuth>
    </AnimatePresence>
  );
};

export default Register;

So, the problem is that, when a component dissapears, i want it to slide to the right, but, doesn't work, i don't know if i wrote my code in a bad way or what is the issue there..

So, if you can help me with this problem, you're the greates, thanks for your time !

Upvotes: 0

Views: 685

Answers (1)

Someone Special
Someone Special

Reputation: 13588

exit only works if you unmount the component.

e.g.

<AnimatePresence>
  { show && <FormAuth exit={.......}>
      ......
    </FormAuth> }

</AnimatePresence>

AnimatePresence allows components to animate out when they're removed from the React tree.

It's required to enable exit animations because React lacks a lifecycle method that:

Notifies components when they're going to be unmounted and Allows them to defer that unmounting until after an operation is complete (for instance an animation).

In your situation, you may want to try to move AnimatePresence so it wraps both Login and Register component.

Upvotes: 1

Related Questions