Hello GSAP community.
I've already used GSAP in multiple react TS projects. Every thing works fine. I'm not posting for any issue
BUT , I'm still a bit in the "fog" when it comes to be sure of the best practices in this particular stack ( React + TS ).
In a very basic way, I'll declare any needed ref in any functional component :
export const AnyFunctionalComponent: FunctionComponent<AnyFunctionalComponentProps> = () => {
const animationTargetRef = useRef<HTMLDivElement>(null);
const scrollTriggerTargetRef = useRef<HTMLDivElement>(null);
gsap.registerPlugin(ScrollTrigger);
then I use a useLayoutEffect ( to be sure all ref have a .current as the DOM is supposed to be completely rendered in the useLayoutEffect ) with the ref as depedancies and I double check that the ref exist as current before creating anyAnimation as gsap , and finally I add the anyAnimation.kill() to ensure every thing is clear if ref used for gsap are unmounted.
useLayoutEffect(() => {
const animationTargetCurrent = animationTargetRef.current;
const scrollerDiv = document.getElementById("scroller");
const scrollTriggerCurrent = scrollTriggerTargetRef.current;
if (animationTargetCurrent && scrollTriggerCurrent && scrollerDiv) {
const anyAnimation = gsap.fromTo(
animationTargetCurrent,
{
opacity: 0,
y: 50,
},
{
y: 0,
opacity: 1,
duration: 1,
ease: "none",
scrollTrigger: {
trigger: scrollTriggerCurrent,
start: "top bottom",
scroller: scrollerDiv,
end: 200,
scrub: 1,
},
}
);
return () => {
anyAnimation.kill();
};
}
}, [animationTargetRef, scrollTriggerTargetRef]);
First of all, is this the good way to clear everything ?
Another step for me , to clear a bit my code is to put the animation code in a useCallback function with the same ref dependancies :
const anyAnimation = useCallback(() => {
const animationTargetCurrent = animationTargetRef.current;
const scrollerDiv = document.getElementById("scroller");
const scrollTriggerCurrent = scrollTriggerTargetRef.current;
if (animationTargetCurrent && scrollTriggerCurrent && scrollerDiv) {
const anyAnimation = gsap.fromTo(
animationTargetCurrent,
{
opacity: 0,
y: 50,
},
{
y: 0,
opacity: 1,
duration: 1,
ease: "none",
scrollTrigger: {
trigger: scrollTriggerCurrent,
start: "top bottom",
scroller: scrollerDiv,
end: 200,
scrub: 1,
},
}
);
return () => {
anyAnimation.kill();
};
}
}, [animationTargetRef, scrollTriggerTargetRef]);
useLayoutEffect(() => {
anyAnimation();
}, [animationTargetRef, scrollTriggerTargetRef]);
I'm not sure the the useCallback, neither the useCallback dependancies are really necessary , as it's already protected (memoized ? ) as the call is made in the useLayoutEffect with the same dependancies ? Right ?
And last, this is not clear enough for me. I'd like to move all animation function anyAnimation in a hook to which we could pass the ref as arguments, to re-use the same code if needed, and clear the component that use it.
BUT > we can't call a hook in a useEffect ( or in a useLayoutEffect ) .
Any suggestions to write this ? Any source that could help ?
In the same time, the first part of the question remains very important. What's the best way to clear any gsap animation and refs .
Thanks in advance for your help/and suggestions.