1

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!

  • 2
    Does this answer your question? [How can I use multiple refs for an array of elements with hooks?](https://stackoverflow.com/questions/54633690/how-can-i-use-multiple-refs-for-an-array-of-elements-with-hooks) – Vencovsky Mar 03 '20 at 16:54
  • 1
    Hi Vencovsky. Yes and...no. Because my question is not how to use multiple refs. But simply: what's the best method to target DOM elements. Btw, thanks for your comment, really appreciate it. – Lucie Bachman Mar 03 '20 at 17:05
  • 1
    `what's the best method to target DOM elements` that's something you should decide. If both work, both can be the best, it just depends on what you think is the best. – Vencovsky Mar 03 '20 at 17:08
  • 1
    `useRef` is the best solution, this is the way to interact with dom nodes in React. Have you tried libraries like react-spring or framer-motion? they are more preformant and use React. – gadi tzkhori Mar 03 '20 at 17:26

0 Answers0