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

:root {
	--dark: #1d1d1d;
	--light: #fff;
	--green: #28a92b;
  --purple: #8d3dae;
}

body {
	background-color: var(--dark);
	color: var(--light);
	font-family: "Signika Negative", sans-serif;
	margin: 0;
  padding: 0;
  height: 100vh;
}

.box {
	width: 100px;
	height: 100px;
  border-radius: 12px;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	background-color: var(--green);
	font-weight: 600;
	color: var(--light);
}

.circle {
	width: 100px;
	height: 100px;
  border-radius: 99%;
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	background-color: var(--purple);
	font-weight: 600;
	color: var(--light);
}

.App {
  display: flex;
  align-items: center;
  justify-content: space-around;
  min-height: 100vh;
}
const { useRef, useLayoutEffect } = React;

function App() {
  const container = useRef();
  const circle = useRef();
  
  useLayoutEffect(() => {
    let ctx = gsap.context(() => {
      // all your animations go in here...
      gsap.to(".box", { rotation: "+=360" });
    }, container); // <- scopes all selector text to the container element

    return () => ctx.revert();
  }, []);

  return (
    <div ref={container} className="App">
      <div className="box">selector</div>
      <div className="circle" ref={circle}>Ref</div>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/gsap@3/dist/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js