Jump to content
GreenSock

Moon Sung Kil

ScrollTrigger on multiple Components (React)

Go to solution Solved by Rodrigo,

Recommended Posts

Hey there, I'm trying to implement a ScrollTrigger on to multiple components using React. In short, I am trying to implement it in a way where every Component rendered will have its own ScrollTrigger, but while reusing  the component it is only firing when it gets to the first component and applies the effects on all the components, I am pretty sure there is a simple way using this with react, but I can"t seem to find, if someone can help me out?

See the Pen Component.js by s (@s) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @Moon Sung Kil and welcome to the GreenSock forums!

 

The main issue is that you're using the same selector in all the instances of your component:

secondSideInfoTL.to(".component_body", {
  duration: 0.5,
  opacity: 1
});

GSAP basically is running that tween on all the elements it finds in the DOM with that class. In the case of your example all three instances of your component. Since version 3.11 GSAP has Context to help with React related stuff and allow users to easily find elements using a specific selector in a given scope. In this case it's as simple as using this code in your component file:

import React, { useEffect, useRef } from "react";
import "./Component.css";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

function Component({ componentColor }) {
  const container = useRef();
  gsap.defaults({ ease: "none", duration: 2 });
  
  useEffect(() => {
    const ctx = gsap.context(() => {
      const secondSideInfoTL = gsap.timeline();
      secondSideInfoTL.to(".component_body", {
        duration: 0.5,
        opacity: 1
      });
  
      ScrollTrigger.create({
        animation: secondSideInfoTL,
        trigger: ".component_body",
        start: "top 20%",
        end: "+=500",
        markers: true,
        toggleActions: "play reset play reset"
      });
    }, container); // <- Scope!
    return () => ctx.revert();
  }, []);
  return (
    <div className="component" ref={container}>
      <div className={`component_body ${componentColor}`}></div>
    </div>
  );
}

Like that GSAP will only look for elements with the class ".component_body" inside that component and not the entire DOM.

Here is a live example:

https://codesandbox.io/s/vibrant-khorana-9x3j3k?file=/src/Component.js

 

Also is always a good idea to create GSAP instances inside a gsap.context() callback in order be able to revert them when the component unmounts.

 

Happy Tweening!

Link to comment
Share on other sites

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.
×