Share Posted April 17, 2019 https://codesandbox.io/s/z21pkzpjkp I'm trying to recreate something I saw someone make, but in React. I'm running into a problem when attempting to animate. As you can see in the code sandbox, I have a card component. In the About.js the card component is rendered through mapping over an array that has the independent information to inject into the cards. The refs I need to access are created in the function "createCards" createCards(card, i) { return ( <Card id={i} key={i} card={card} info={this.state.aboutCards} ref={card => { this["card" + i] = card; }} /> ); } } So 3 references are made, card0, card1, and card2. Those are the refs I need to access, but I want to access them in Card.js if thats possible. So I can create a timeline and do all of the animations over there, because i'll be animating the image, and header. When i'm in Card.js and console.log(this.refs) in the component did mount I get 3 objects. The problem is i'm not sure how to use them in Card.js for example: class Card extends Component { tl = new TimelineLite({ paused: true }); *i dont know how to initalize as null here* componentDidMount() { this.tl.to("i dont know what to put here", 0.9, { y: 350, x: -400 }, 0.2); } render() { Or...should i be doing the animation in About.js? i've tried something like this: and it's not really working either... class About extends Component { constructor(props) { super(props); this.createCards = this.createCards.bind(this); this.tl = new TimelineLite({ paused: true }); this.card0 = null; this.card1 = null; this.card2 = null; } componentDidMount() { this.tl.to(this.card0, 0.9, { opacity: 0 }); this.tl.play(); } See the Pen by s (@s) on CodePen Link to comment Share on other sites More sharing options...
Share Posted April 17, 2019 Welcome to the forums, @Alexander75. I'm not much of a React guy, so I may not be much help. @Rodrigo is our resident expert - did you read his article? https://greensock.com/react Link to comment Share on other sites More sharing options...
Share Posted April 17, 2019 Hi and welcome to the GreenSock forums. The fist thing here is that when you create a ref in directly in a component, you get the component instance and not the DOM node or tree that the component ultimately renders: class MyApp extends Componetn { constructor(props) { super(props); this.myCard = null; } componentDidMount () { console.log(this.myCard); // returns a React component object } render () { return <div> <Card ref={card => myCard = card} /> </div>; } } That because the ref callback is being called in a React Component instance and not a DOM node created in JSX. Then is not clear where you want to create the animations; In the parent component or on each card?. If you want to create the animations in the parent component then you should use Forwarding Refs in order to store a reference to the DOM node that sits at the top of the DOM tree created by that component. Forwarding refs is a bit of a complex resource for someone that is just staring with React, specially if your Card component can't be transformed into a functional component. If your Card component can be transformed into a functional component, then is pretty easy. This is an extremely simple example of using forward refs to create an animation with GSAP: https://stackblitz.com/edit/react-forwarding-refs-gsap An alternative is to use React Transition Group in order to create the animations inside each Card component. This approach can also be a bit convoluted as shown here: https://stackblitz.com/edit/gsap-react-transition-group-list Finally if you want to access the DOM element directly inside each instance of the Card component without all the hassle of React Transition Group you're very close in fact. Right now you have this on your Card component: class Card extends Component { tl = new TimelineLite({ paused: true }); componentDidMount() { console.log(this.refs); } render() { return ( <div className="slide"> <div className="card"> <div className={`${this.props.card.id} card-img`} /> <div className="card-content" ref> <p className="card-theme">{this.props.card.theme}</p> <h2 className="card-header">{this.props.card.header}</h2> <p className="card-para"> lorem lorem</p> <a className="card-link" href="#"> Read </a> </div> </div> <div className="prevnext"> <button className="pn-btn" id="prev" /> <button className="pn-btn" id="next" /> </div> </div> ); } } Keep in mind that the ref is a callback that, used as an attribute in the JSX code, grabs whatever is returned from the tag where is used, in this case a <div> element, but is a function, now you're only referencing that function but you're not doing anything with it. You have to create a reference to the DOM element in the constructor and then use the callback to update it at render time: class Card extends Component { constructor(props){ super(props); this.tl = new TimelineLite({ paused: true }); this.card = null; } componentDidMount() { console.log(this.card); // returns the div element } render() { return ( <div className="slide"> <div className="card"> <div className={`${this.props.card.id} card-img`} /> <div className="card-content" ref={div => this.card = div}> <p className="card-theme">{this.props.card.theme}</p> <h2 className="card-header">{this.props.card.header}</h2> <p className="card-para"> lorem lorem</p> <a className="card-link" href="#"> Read </a> </div> </div> <div className="prevnext"> <button className="pn-btn" id="prev" /> <button className="pn-btn" id="next" /> </div> </div> ); } } That particular use will allow you to use the <div> element in your GSAP instance with no problems. Hopefully this is enough to get you started. Happy Tweening!! 1 Link to comment Share on other sites More sharing options...
Share Posted April 18, 2019 you really must be a superhero 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