trunks Posted April 11, 2021 Share Posted April 11, 2021 Hi all, new to the GSAP library and loving it! I'm trying to implement ScrollTrigger with Next.js but for some reason when I define a timeline with ScrollTrigger it shows me the following error. TypeError: Cannot read property '_gsap' of undefined I'm not sure though if the error it's Next.js related. Imports: import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'; import { useEffect, useRef } from 'react'; Function: const triggerRef = useRef(null); const titleRef = useRef(null); const textRef = useRef(null); const tl = gsap.timeline({ // yes, we can add it to an entire timeline! scrollTrigger: { trigger: triggerRef.current, start: 'top center', toggleActions: 'play none none reverse', markers: true, }, }); useEffect(() => { tl.from(titleRef.current, { duration: 0.5, autoAlpha: 0, ease: 'power1.out', delay: 0.1, y: 10, }).from(textRef.current, { duration: 0.5, autoAlpha: 0, ease: 'power1.out', delay: 1, y: 10, }); }, []); Any ideas? Thank you. Link to comment Share on other sites More sharing options...
Solution BrianCross Posted April 11, 2021 Solution Share Posted April 11, 2021 Not sure if this is causing your exact error but you need to put this: const tl = gsap.timeline({ // yes, we can add it to an entire timeline! scrollTrigger: { trigger: triggerRef.current, start: 'top center', toggleActions: 'play none none reverse', markers: true, }, }); in your useEffect callback. Otherwise the timeline instance will get re-created every time the component re-renders. 2 Link to comment Share on other sites More sharing options...
trunks Posted April 11, 2021 Author Share Posted April 11, 2021 19 minutes ago, BrianCross said: Not sure if this is causing your exact error but you need to put this: const tl = gsap.timeline({ // yes, we can add it to an entire timeline! scrollTrigger: { trigger: triggerRef.current, start: 'top center', toggleActions: 'play none none reverse', markers: true, }, }); in your useEffect callback. Otherwise the timeline instance will get re-created every time the component re-renders. It works but is this the correct way to do it? Because the react examples that I've found the gsap.timeline is out of useEffect. Thanks for the reply. Link to comment Share on other sites More sharing options...
BrianCross Posted April 11, 2021 Share Posted April 11, 2021 No it needs to be inside useEffect because the DOM needs to be rendered before you can animate it. 2 Link to comment Share on other sites More sharing options...
Rodrigo Posted April 11, 2021 Share Posted April 11, 2021 1 hour ago, trunks said: Because the react examples that I've found the gsap.timeline is out of useEffect. Brian is right, it has to be inside the useEffect or in the componentDidMount hook (if you're using class components). Perhaps what you've seen before is that a reference is being created for a GSAP instance outside a useEffect hook in order to keep it through re-renders and perhaps update it in case of a specific state or prop update: const myTween = useRef(gsap.timeline({ paused: true })); const myRef = useRef(); useEffect(() => { myTween.current.to(myRef.current, { duration: 1, x: 100, y:100 }); return (() => { myTween.current.kill(); }); }, []); Happy Tweening!!! 3 Link to comment Share on other sites More sharing options...
trunks Posted April 11, 2021 Author Share Posted April 11, 2021 2 minutes ago, Rodrigo said: Brian is right, it has to be inside the useEffect or in the componentDidMount hook (if you're using class components). Perhaps what you've seen before is that a reference is being created for a GSAP instance outside a useEffect hook in order to keep it through re-renders and perhaps update it in case of a specific state or prop update: const myTween = useRef(gsap.timeline({ paused: true })); const myRef = useRef(); useEffect(() => { myTween.current.to(myRef.current, { duration: 1, x: 100, y:100 }); return (() => { myTween.current.kill(); }); }, []); Happy Tweening!!! Thanks for the explanation! 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now