Hello, I'm trying to implement mounting and unmounting animations to conditionally rendered elements in my React component, similar to the example given in the Advanced React docs:
{!joined && (
<div ref={usernameFormRef}>
<Button onClick={() => onSubmit()}>
Join
</Button>
</div>
)}
{joined && (
<div ref={controlsRef}>
<Button onClick={() => onLeave()}>
Leave
</Button>
</div>
)}
const [joined, setJoined] = useState(false);
const { contextSafe } = useGSAP({ scope: controlsScope });
const tl = gsap.timeline();
const onSubmit = contextSafe(() => {
tl.to(usernameFormRef.current, {
opacity: 0,
yPercent: 200,
duration: 0.7,
ease: "back.in(2)",
onComplete: () => setJoined(true),
});
tl.from(controlsRef.current, {
opacity: 0,
yPercent: 200,
duration: 0.7,
ease: "back.out(2)",
});
});
const onLeave = contextSafe(() => {
tl.to(controlsRef.current, {
opacity: 0,
yPercent: 200,
duration: 0.7,
ease: "back.in(2)",
onComplete: () => setJoined(false),
});
tl.from(usernameFormRef.current, {
opacity: 0,
yPercent: 200,
duration: 0.7,
ease: "back.out(2)",
});
});
The problem I faced was that the onComplete function seemed to fire at the end of the timeline, not between each tween. This results in the tl.to unmounting/exit animation working as expected unlike tl.from which results in an abrupt mounting of the controlsRef element. I have also tried implementing without a timeline but ran into the same results. What exactly am I missing here? Any help would be much appreciated. I have also attached my component directly if more context is needed.
MultiplayerControls.tsx