<div id="app"></div>
@import url('https://fonts.googleapis.com/css2?family=Signika+Negative:wght@400;600&display=swap');

body {
  font-family: "Signika Negative", sans-serif, Arial;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  overflow: hidden;
    background-color: #28292b;
  color: #fffce1;
}

h1 {
  text-align: center;
  font-weight: 400;
}

#app {
  display: flex;
  justify-content: center;
}

.box {
  width: 80px;
  height: 80px;
  background: dodgerblue;
  margin: 10px;
  float: left;
  opacity: 0;
  border-radius: 6px;
  transform: scale(0.3);
}
let { useRef, useEffect, forwardRef } = React;

let data = [
  { id: 0 },
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 }
];

// To get a ref from a child component, we must forward
// the ref up to the parent
let Box = forwardRef((props, ref) => {
  return <div className="box" ref={ref}></div>
});

let App = () => {
  let boxRefs = useRef([]);
  
  useEffect(() => {
    gsap.to(boxRefs.current, {
      opacity: 1,
      scale: 1,
      duration: 1,
      stagger: 0.1,
      repeat: -1,
      repeatDelay: 1,
      yoyo: true
    });
  }, []);
  
  return (
    <div>
      <h1>React forwarding refs</h1>
      {data.map((item, i) => <Box key={item.id} ref={e => boxRefs.current[i] = e} />)}
    </div>
  );
}

ReactDOM.render(<App/>, document.querySelector('#app'));
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://assets.codepen.io/16327/gsap-latest-beta.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js