Share Posted May 26, 2021 Hello GSAP gang, I have a little bit of a situation going on. I understand that there's already a post on this topic, but I need help with this one as well. I've got some code that I have tried out but it seems that I've been unable to fix this issue. The coding sandbox comes up with an error: "Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node."https://codesandbox.io/s/react-router-re-render-8btmz?file=/src/index.js I was wondering if any of you guys had any experience in this, and how to get it so that the React router link works as intended? Thanks Link to comment Share on other sites More sharing options...
Share Posted May 26, 2021 Hi @Tonycre8, I didn't have a change to dive into this, yet, but at a glance: Make sure you're doing garbage cleanup on your ScrollTrigger too (https://greensock.com/docs/v3/Plugins/ScrollTrigger/kill()), via ScrollTrigger.getById('yourID').kill();. Also, you're still using the old gsap2 syntax (you not longer need to use TimelineLite, etc) you can now use cont slide = gsap.timeline();. 1 Link to comment Share on other sites More sharing options...
Author Share Posted May 26, 2021 Hey there. Thanks for the response. 10 minutes ago, elegantseagulls said: Hi @Tonycre8, I didn't have a change to dive into this, yet, but at a glance: Make sure you're doing garbage cleanup on your ScrollTrigger too (https://greensock.com/docs/v3/Plugins/ScrollTrigger/kill()), via ScrollTrigger.getById('yourID').kill();. Also, you're still using the old gsap2 syntax (you not longer need to use TimelineLite, etc) you can now use cont slide = gsap.timeline();. I'll come back to updating the syntax in a short while, but about the potential solution. What would the ID be? I've tried using this as well as the other bits of cleanup I've done. ScrollTrigger.kill() in my code since then, but it hasn't seemed to work either. Link to comment Share on other sites More sharing options...
Share Posted May 26, 2021 You'll want to set a unique id for your ScrollTrigger. ScrollTrigger.create({ id: 'slideID', ... }) 2 Link to comment Share on other sites More sharing options...
Author Share Posted May 26, 2021 We seemed to have found a fix! Well, my brother worked on it whilst I was waiting for someone to turn up for a meeting. Based on a comment from here: We found that the issue is actually just adding a surrounding div to my home.js code, so something like this: return ( <div> <div className="sections"> <section className="section" style={{ background: "white" }}> <div> <Link to="/blog">Link</Link> </div> </section> <section className="section" id="section2" style={{ background: "green" }} > <p>Section 2</p> </section> <section className="section" id="section3" style={{ background: "blue" }} > <p>Section 3</p> </section> <section className="section" id="section4" style={{ background: "orange" }} > <p>Section 4</p> </section> <section className="section" id="section5" style={{ background: "yellow" }} > <p>Section 5</p> </section> </div> </div> ); Although we are still unsure of why this works, it seems to be a working solution. 1 Link to comment Share on other sites More sharing options...
Share Posted June 3, 2021 Hi @Tonycre8 GSAP needs to do some cleanup before the component gets removed from the DOM, so you should create your scroll triggers inside useLayoutEffect like this. There should be no need to add an extra div using this method. useLayoutEffect(() => { let st = ScrollTrigger.create({ pin: true, ... }); return () => { st.kill(); }; }, []); 2 2 Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 Are there any demos on this? Cannot seem to get it to work. I am killing the ST and can see they regenerate. Normal animations work but the issue seems to be with pinning. Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 Welcome to the forums @spirconi Can you make a demo on CodeSandbox showing the problem? And did you try useLayoutEffect and make sure the component you are pinning is not fragment? Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 16 minutes ago, OSUblake said: Welcome to the forums @spirconi Can you make a demo on CodeSandbox showing the problem? And did you try useLayoutEffect and make sure the component you are pinning is not fragment? I have not tried to make a demo yet, I was hoping one existed I could try to work it out from first. Actually, I tried useLayoutEffect, and whilst it did not work, it may provide a clue. With useEffect, the pins work fine on initial load. The issue is when i go to / come back from another page it just ignores the pinned scrolltriggers. I notice the markers work as expected. I can see the top marker stay in place, which is met by the element start marker. When i come back to the page, the markers are in the same place but are just ignored. I noticed with useLayout effect the top marker moves up the page, so the pin never triggers. So that didnt work. I am using locomotive scroll setup (all works as expected minus this issue). I am suspecting it may be something to do with that setup up rather than gsap specifically. Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 I just noticed if i resize the window it works (with useEffect), maybe that will flag something that might be the cause? Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 Ok, I added the following to the parent component which seems to have done the trick. useEffect(() => { ScrollTrigger.refresh(); }, [ScrollTrigger.getAll()]); Link to comment Share on other sites More sharing options...
Share Posted October 22, 2021 Just be careful with that code. It's going to call refresh every time there is a re-render. You might want to add a console.log in there just to test and make sure it's not being called a lot. Link to comment Share on other sites More sharing options...
Share Posted October 28, 2021 On 10/23/2021 at 12:34 AM, spirconi said: Ok, I added the following to the parent component which seems to have done the trick. useEffect(() => { ScrollTrigger.refresh(); }, [ScrollTrigger.getAll()]); Here to report that I had the exactly same issue and this code solved it. Navigating to another page and back breaks scroll triggers. Link to comment Share on other sites More sharing options...
Share Posted October 28, 2021 1 hour ago, hereandnow said: Navigating to another page and back breaks scroll triggers. Are you still having trouble? Just an FYI about the code posted above. It will run on every render and is basically the same as having an effect with no dependencies . // has the same effect useEffect(() => { ScrollTrigger.refresh(); }, [ScrollTrigger.getAll()]); // as this useEffect(() => { ScrollTrigger.refresh(); }) This is due to way React detects changes using Object.is. let same = Object.is(ScrollTrigger.getAll(), ScrollTrigger.getAll()) console.log("SAME", same) // false Link to comment Share on other sites More sharing options...
Share Posted October 28, 2021 In my instance it is a very light app and only re rerenders twice as there is not much interactivity. I needed a fast solution to get the site live, but noted this is not recommended and will look for a better solution once I have chance to go back to it. 1 Link to comment Share on other sites More sharing options...
Share Posted November 4, 2021 Hi guys. I can report having the same error on route change of a Next.js app (Next Router, React 17.0.2, Next 11.1.2, GSAP 3.8.0). It doesn't occur on a forced reload, just when navigating away from the page via Next router. If I removed the Pinning, error went away. Note, I was using Refs for all dom targeting, and a custom useLayoutEffect hook I wrote for Next (which only runs Isomorphically). The hook had cleanup deps defined and killing ScrollTrigger on unmount didn't prevent the error. In the end, the fix was to ensure the target ref was NOT on the component's parent element. The target ref seems to need a wrapper / parent so the injected pin spacers are actually child elements of the component. Interestingly, this also improved render times when navigating to the page. Still investigating specifics. 2 2 Link to comment Share on other sites More sharing options...
Share Posted November 4, 2021 Hi @stephens Do you think you can put what you did in a CodeSandbox so others can see? 1 Link to comment Share on other sites More sharing options...
Share Posted February 1, 2022 Wrapping the scrolltrigger pin in a div didn't work for me as it seemed to change the scrolltrigger progress values? Killing scrolltrigger on useEffect/useLayoutEffect unmount also didn't work. What worked was manually triggering kill() before unmounting the component. So something like this... const backBtnPress = () => { animationsRef.current.menuFadeIn.vars.onReverseComplete = () => { sTrigger.current.kill(); setNav('more') } animationsRef.current.menuFadeIn.reverse() } 1 1 Link to comment Share on other sites More sharing options...
Share Posted May 2, 2022 Using VueJS, adding the following to the router fixed the issue: router.beforeEach((to, from) => { if (from.path !== to.path) ScrollTrigger.getAll().forEach(el => el.kill()) return true }) router.afterEach((to, from) => { if (from.path !== to.path) { ScrollTrigger.refresh(); ScrollTrigger.update() } }) 2 Link to comment Share on other sites More sharing options...
Share Posted May 2, 2022 Thanks for sharing your solution. Just FYI, you don't need to call ScrollTrigger.update() after calling ScrollTrigger.refresh() (it's redundant). 1 Link to comment Share on other sites More sharing options...
Share Posted March 9 Hello, in my case the problem was when I load my react website, the initial current component which refreshes it is fine and the scroll position is also good but after we navigate to other components their I have images which load after I navigate to that component because of which scroll trigger position fails to load the right position as it doesn't refresh after the image loads. So, what I did is in react, there is an attribute called onLoad which gets triggered after the image loads. Hence, onLoad={()=>ScrollTrigger.refresh()} solved my problem. Link to comment Share on other sites More sharing options...
Share Posted March 9 Hi @Arman_ and welcome to the GreenSock forums! It's pretty tough to troubleshoot without a minimal demo - the issue could be caused by CSS, markup, a third party library, your browser, an external script that's totally unrelated to GSAP, etc. Would you please provide a very simple CodePen or CodeSandbox that demonstrates the issue? Please don't include your whole project. Just some colored <div> elements and the GSAP code is best (avoid frameworks if possible). See if you can recreate the issue with as few dependancies as possible. If not, incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, then at least we have a reduced test case which greatly increases your chances of getting a relevant answer. Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen If you're using something like React/Next/Vue/Nuxt or some other framework, you may find StackBlitz easier to use. We have a series of collections with different templates for you to get started on these different frameworks: React/Next/Vue/Nuxt. Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 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