Reputation: 5819
I thought on ever render framer motion would re-do my animation because the inital is set to hide and the animate is set to show. But this is not the case.
How can I get this to re-play the animation on each state change ?
import React, { useEffect, useState } from "react";
import { motion} from "framer-motion";
import styled from "styled-components";
const Screen = () => {
const [state, setState] = useState(1);
useEffect(() => {
setInterval(() => {
setState(Math.random());
}, 4000);
}, []);
return (
<Title variants={variants} animate="show" initial="hide">
{console.log("re-render")}
{`screen ${state}`}
</Title>
);
};
const Title = styled(motion.div)`
color: red;
`;
export const variants = {
show: {
opacity: 1,
y: 0,
transition: {
ease: "easeOut",
duration: 0.3
}
},
hide: {
y: -20,
opacity: 0
}
};
export default Screen;
Upvotes: 7
Views: 23210
Reputation: 1117
You can change animation on state as well.
Something like this:
export const SingleListView = () => {
const [animation, setAnimation] = useState(false);
const variants = {
show: {
opacity: 1,
y: 0,
transition: {
ease: 'easeOut',
duration: 0.3,
},
},
hide: {
y: -20,
opacity: 0,
},
};
return (
<>
<motion.div key="animation-on-state" variants={variants} animate={animation ? 'hide' : 'show'}>
<div>{`${animation}`}</div>
</motion.div>
<button onClick={() => setAnimation((state) => !state)}>
BUTTON {`${animation}`}
</button>
</>
);
};
Upvotes: 4
Reputation: 18506
If you just want to remount element use a key
prop on it, like that:
return (
<motion.div key={state} variants={variants} animate={'show'} initial="hide">
{`screen ${state}`}
</motion.div>
);
Codesandbox (please provide Codesandbox with reproduction in the future)
It looks weird but it works if that is the effect that you want.
For smoother animation I would use animation controls or AnimatePresence
probably.
Upvotes: 26