I'm wondering what is the best method to target DOM elements with React Hooks, to animate them with libraries like Animejs or GSAP that need dom elements to animate them. I wrote so many similar posts, but I didn't find the answer I'm looking for.
Here's a short code structure, to illustrate my question:
function App() {
return (
<div className="container">
<div className="intro">
<div className="title">
<h1>My General Title.</h1>
</div>
<div className="presentation">
<p>This is my description.</p>
</div>
</div>
<div className="pictures">
<ul>
<li><img src="myPicture.jpg" /></li>
<li><img src="myPicture.jpg" /></li>
<li><img src="myPicture.jpg" /></li>
</ul>
</div>
</div>
);
}
First way : Only using useRef ?
function App(){
// Container
let containerRef = useRef(null);
// Intro
let introRef = useRef(null);
let titleRef = useRef(null);
let presentationRef = useRef(null);
// Pictures
let picturesRef = useRef(null);
let picture1Ref = useRef(null);
let picture2Ref = useRef(null);
let picture3Ref = useRef(null);
return(
<div className="container" ref={container}>
<div className="intro" ref={introRef}>
<div className="title">
<h1 ref={titleRef}>My General Title.</h1>
</div>
<div className="presentation">
<p ref={presentationRef}>This is my description.</p>
</div>
</div>
<div className="pictures" ref={picturesRef}>
<ul>
<li><img ref={picture1Ref} src="myPicture.jpg" /></li>
<li><img ref={picture2Ref} src="myPicture.jpg" /></li>
<li><img ref={picture3Ref} src="myPicture.jpg" /></li>
</ul>
</div>
</div>
);
}
→ Disadvantages : So many repetitions, if we want to target a lot of DOM elements.
Second way : Using useRef + useState + useEffect
function App(){
// Container
let containerRef = useRef(null);
// Intro
let introRef = useRef(null);
// Pictures
let picturesRef = useRef(null);
const [intro, setIntro] = useState({ title: "", presentation: "" });
const [pictures, setPictures] = useState({ pictures: [] });
useEffect(() => {
// Intro
const myNewTitle = introRef.current.children[0].children[0];
const myNewPresentation = introRef.current.children[1].children[0];
setIntro({...intro, title: myNewTitle, presentation: myNewPresentation });
// Pictures
const myNewPictures = picturesRef.current.children[0].children;
const myNewPicturesArray = [];
[...myNewPictures].map(item => myNewPicturesArray.push(item.children[0]));
setPictures({...pictures, pictures: myNewPicturesArray });
}, [])
return(
<div className="container" ref={container}>
<div className="intro" ref={introRef}>
<div className="title">
<h1 ref={titleRef}>My General Title.</h1>
</div>
<div className="presentation">
<p ref={presentationRef}>This is my description.</p>
</div>
</div>
<div className="pictures" ref={picturesRef}>
<ul>
<li><img ref={picture1Ref} src="myPicture.jpg" /></li>
<li><img ref={picture2Ref} src="myPicture.jpg" /></li>
<li><img ref={picture3Ref} src="myPicture.jpg" /></li>
</ul>
</div>
</div>
)
}
Perhaps using useEffect is not the better method to target elements. Actually I don't know.
Why did I make this ? Because if I'm using libraries like animejs or gsap, I'll need to access so many times to the DOM elements. And perhaps using the useState is the better idea, isn't it ?
In fact, the easiest method to target DOM element for creating animations with the libraries I mentioned, could be to use querySelector or querySelectorAll. But I heard this is forbidden with React.
I need advices and some help to know how to perfectly target DOM elements. And if one of my method looks good (or not). Thanks!