Harshal Patil
Harshal Patil

Reputation: 20980

How to access the DOM element of the child component in Preact with hooks?

I am using Preact with hooks. I have following button component:

export function Button(props) {
    return (
        <button class={props.class}>{props.children}</button>
    );
}

I have another parent component where I need to access actual DOM element button for animation purpose.

export function Parent(props) {
    const buttonElm = useRef(null);

    useEffect(() => {

        console.log(buttonElm.current);

        // Animate button using popmotion or similar
    });

    return (
        <div>
            <Button ref={buttonElm}>Click me to animate</Button>
        </div>
    );
}

However, there is a problem. The buttonElm.current points to JSX object i.e. Button but not the DOM element button. I need buttonElm to point to actual DOM element. How do I do that?

Should I go ahead and use buttonElm.current.base property? But that does not feel idiomatic with hooks.

Also, I have two questions.

  1. How does ref behave when I am setting it on a Preact component that returns multiple elements using <Fragment />.
  2. Second, is accessing the children's DOM element for animation purpose acceptable/correct practice in Preact/React? (I can wrap my component in another wrapper div but that causes more animation headaches than solving the problem)

Upvotes: 2

Views: 1980

Answers (1)

Kais
Kais

Reputation: 2008

You need to pass ref as props to your child component. By doing this buttonElm will point to actual Button DOM element.

  export function Button(props) {
        return (
            <button class={props.class} ref={props.buttonElm}>{props.children}</button>
        );
    }

export function Parent(props) {
    const buttonElm = useRef(null);

    useEffect(() => {

        console.log(buttonElm.current);

        // Animate button using popmotion or similar
    });

    return (
        <div>
            <Button buttonElm={buttonElm}>Click me to animate</Button>
        </div>
    );
}

Upvotes: 2

Related Questions