Jump to content


GSAP + React.js The quest for best practices

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I've done a great deal of looking around... I could be off, but there seems to be a lack of authority on best practices for GSAP and react.


There once was a 'gsap-enhancer' (no longer supported) that enabled jQuery-like targeting of dom nodes and their children. Syntax was easy.


From looking around on the interwebs-- FindDOMnode() was once recommended for targeting... & then "ref='' "  attrs (with it's callback feature--which is a bit above my paygrade to understand at the moment


I'm frankly, beginning to feel a bit discouraged from using GSAP in react altogether because there is such a broad spectrum of misinformation out there.




In the comments, the author says "use refs!" but publishes code examples using findDOM node() ?...


It's endlessly frustrating for people to learn about this incredibly powerful, wonderful library.


If only a tutorial were available with a simple example of iterating over some list-items using best practices... it would be a big help to a huge number of people.


There are a few similar unanswered questions on stack overflow re GSAP and react as well... Clearly there is a gap to fill...


---That said, if anyone could point me in the right direction, I'll write the article myself for noobs like me who remain "out of the loop" ;)




For reference, I did this thing without realizing what a "breach" of best practices it is.

See the Pen QQqgrp by beau_dev (@beau_dev) on CodePen


I would so like to improve it so that I can learn about using GSAP and react properly.


Anyway... Best wishes & many thanks in advance to whoever could point me in the right direction.




Link to comment
Share on other sites

I'm trying to pick this all apart ... there is a lot going on in the question, and even more going on in the code pen. Upfront confession ... I don't use React for anything. So my understanding of the question maybe because of that.


I think the question is ... "With React, how do I target and tween specific set of DOM elements using GSAP?" Is that the question?

  • Like 1
Link to comment
Share on other sites

Hey Beau,


I understand the frustration. The reality of things is that React works in a declarative way and the discourage to use string refs and find dom node has mostly to do with some specific issues and some excessively paternal approach by the React team. The paternal issue comes from the fact that the deprecation of string refs has to do with some edge cases and because of a few things that could go wrong the entire API is changed for everyone. Take GSAP for example, Jack does His best to ensure that GSAP serves as many scenarios as possible but never compromises performance, file size nor legacy support, and when those changes do come, believe me there is a lot of questions and samples going around before the decision is made. But that's how GSAP works and perhaps we've been a little spoiled by that, but that's how serious Jack and Carl are about how this works.


IMHO there's nothing wrong with using string refs and fond dome node if you know what you're doing. At some point developers have to take responsibility for the code they write and not expect that the frameworks make all kind of loops and hoops to ensure that every blunder is supported. As I mentioned in another post yesterday this is some very specific issue, because you have to take in consideration the lifecycle of your app and it's components in order to make the best decision. There are some cases that you can safely reference the elements using the classic get element by id if, when you create the variable you're sure that the DOM node will be rendered in the app. In other cases if you're not sure is better to use refs.


This simple codepen goes into the detail of how refs are accepted today:


See the Pen aYZexp?editors=0010 by rhernando (@rhernando) on CodePen

In the console you'll find an array with all the rendered elements that can be used with GSAP. This is the so called "React way" for referencing DOM nodes.


Now the pain comes when you're using a third party component that doesn't expose the DOM node, like this case:

import ThirdParty from "third-party";

const elements = ["label-1", "label-2", "label-3", "label-4"];

class MyApp extends Component{
    this.elements = [];
    return <div>
        elements.map( e => {
      	  <ThirdParty key={e} ref={ node => this.elements.push(node) } />


In this case the array will have a collection of the four React components being rendered and not the nodes being added to the DOM. In this case find dom node comes in handy because it allows to reference the actual element in the screen. If the plan is indeed remove find dome node from ReactDOM then things will get more complicated, because developers will have to bake their own version of this component in order to expose the ref to the DOM node  or the developers of third party components will have to come up with some way to find those references. One of the simple ways to do this could be for components to accept an id property in order to later reference that and get access to the DOM node.


Finally don't get discouraged from using GSAP with React, there are ways to use it and the more is being used, the React team will become aware that to create complex animations and rich environments GSAP is the way to go and they'll have to come with some way to actually gain access to the dom elements. Right now we have to keep using this type of approaches with the hope that things will change and become simpler in the future. Also keep in mind that the article you mention was written when React was in version 15 and string refs and find dom node were not deprecated and that wasn't a long time ago, unfortunately this world moves way to fast and doesn't wait for anyone...


Happy Tweening!!!

  • Like 5
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Shaun Gorneau said:

I'm trying to pick this all apart ... there is a lot going on in the question, and even more going on in the code pen. Upfront confession ... I don't use React for anything. So my understanding of the question maybe because of that.


I think the question is ... "With React, how do I target and tween specific set of DOM elements using GSAP?" Is that the question?


Yes.. Sorry :) early morning post. I'm losing the powers of articulation :).


This is one thread I should've added. It's very useful for context.


Link to comment
Share on other sites

31 minutes ago, Rodrigo said:



Really, really helpful and interesting. The second example was j-u-u-st above my head without working through the code. But it's great motivation for me to skip out of work & start my weekend early :)


Many thanks again for the helpful advice.!


  • Like 1
Link to comment
Share on other sites

Most definitely out of my comfort zone here...

This code was created with the help of craig and pointC on these forums.


But this is what I've got so far... The effect is staggering  ? .   (...sorry).... 


See the Pen BrLYpE?editors=0011 by beau_dev (@beau_dev) on CodePen


What I'm really looking to do is to randomly slowly flash them (at speeds within a random range that is rather slow).


So far, they stagger down a line...  However, I think 


the code:



ref={ node => this.elements.push(node) }


pushing elements to an array


...and THEN .map() that array with timelines... (I think...).


Perhaps that will produce the randomness of the actual targets.



(FYI)...The jQuery rendered effect I'm looking to produce is here:

See the Pen xWVrwo?editors=1010 by beau_dev (@beau_dev) on CodePen



At any rate... I've made lots of progress out of my comfort-zone and am very encouraged. It has been painful.


But... I'm beginning to believe.


::insert morpheus.gif here::


Thank you again, for the help.


After I sleep a bit... I'll revisit this with better results hopefully.


Perhaps documenting this progress may help others for future reference.






Link to comment
Share on other sites

Hey Beau,


There's absolutely nothing wrong with the React part of your code, that's working as expected. You're generating the refs for each DOM node and using them in the componentDidMount method. The issue has to do with the GSAP part.


Right now you're creating an instance in the timeline for each SVG element but you're not passing a position parameter, so GSAP is putting each instance at the end of the timeline, therefore each element is animated in a sequential way.


In order to achieve what's happening in the second codepen you can use two approaches:


Option One

Add every single instance at the start of the timeline using the position parameter at 0 and add random delays to each one in order to create the overlapping.

const tl = new TimelineMax();

waves.forEach( item => {
  tl.to( item, duration, {opacity: random(), delay: randomDelay()}, 0 );

That zero at the end tells GSAP to add the instance at the very start of the timeline, ie, time zero. The random functions are for creating random opacity and delay numbers.


Option Two

Create a random position parameter for each instance based on the duration of the timeline when that particular instance is being added to the timeline or by forcing the timeline to have a specific duration using the (you guessed... the duration method). Now this might be a little more complicated because you'll have to access the duration of the timeline or set a fix duration for it. Check this from the API:



So I'd recommend using option one if you can.


Finally check this from professor @Carl in order to get a great grasp of the position parameter.




Happy Tweening!!

  • Like 5
Link to comment
Share on other sites

7 hours ago, Rodrigo said:

There's absolutely nothing wrong with the React part of your code


Wow... never read those words before. :)





Been working on this all day... 

You are a genius.


thank you so much!


Got it working on local host...


As soon as I get it into codepen, I'll post something.


Thanks so so much, again.


  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.