Suisse
Suisse

Reputation: 3613

Add types for passing a ref state setter from parent to child with TypeScript in React

I lost some hours and don't get this. I tried a ton of examples, but nothing worked. How do I solve these sort of challenges? How do I know what kind of types Typescript wants for those things, and why the hell should ANYONE do such things with typescript, since in JS it just works!

I just want to pass my useState from parent to the child, and there I want to set a Ref of a div to the useState so that the parent can manipulate the div (and its children).

const Parent: React.FC<iParent> = ({title}) => {
    
    const x = React.useRef() as React.MutableRefObject<HTMLDivElement>;;
    const refSetter = useState(x);

  return(
       <Child setMyRef={refSetter} />
  )

}



interface iChild {
  setMyRef: Dispatch<SetStateAction<React.MutableRefObject<HTMLDivElement>>>;
}
const Child: React.FC<iChild> = ({setMyRef}) => {
  
  const myRef = useRef(???type?);
  
  useEffect(() => {
    if(myRef.current){
        setMyRef(myRef);
    }
  }, [])

  return(
       <div ref={myRef} />
  )

}

Upvotes: 1

Views: 1147

Answers (1)

Youssouf Oumar
Youssouf Oumar

Reputation: 45845

You can do it as below. A way to know what type for what variable is to read the error you get and also what you see when you hover over one.

import {Dispatch, FC, RefObject, SetStateAction, useEffect, useRef, useState } from "react";

interface iChild {
  setMyRef: Dispatch<SetStateAction<RefObject<HTMLDivElement> | null>>;
}
const Child: FC<iChild> = ({ setMyRef }) => {
  const myRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    setMyRef(myRef);
  }, []);

  return <div ref={myRef} />;
};

const Parent: FC<iParent> = ({ title }) => {
  const [ref, refSetter] = useState<RefObject<HTMLDivElement> | null>(null);

  useEffect(() => {
    console.log(ref?.current);
  }, [ref, ref?.current]);

  return <Child setMyRef={refSetter} />;
};

Edit on CodeSanbox

Upvotes: 1

Related Questions