8

My react component needs a callback ref only. I'm using useState for a callback ref.

const [refElement, setReference] = useState(null); 
 

Inside render:

<div
// this ref is throwing ts error
   ref={setArrowElement}
   style={styles.arrow}
   id="arrow"
/>

Typescript error : On tsc

- error TS2322: Type 'Dispatch<SetStateAction<null>>' is not assignable to type 'string | ((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined'.
  Type 'Dispatch<SetStateAction<null>>' is not assignable to type '(instance: HTMLDivElement | null) => void'.
    Types of parameters 'value' and 'instance' are incompatible.
      Type 'HTMLDivElement | null' is not assignable to type 'SetStateAction<null>'.
        Type 'HTMLDivElement' is not assignable to type 'SetStateAction<null>'.
          Type 'HTMLDivElement' provides no match for the signature '(prevState: null): null'.

216                         ref={setReference}
                            ~~~

  ../../node_modules/@types/react/index.d.ts:145:9
    145         ref?: LegacyRef<T>;
                ~~~
    The expected type comes from property 'ref' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'


Found 1 error.
5
  • ref should be an HTML element, and you're assigning it a setState function Commented Aug 7, 2020 at 9:34
  • why do you useState instead of useRef Commented Aug 7, 2020 at 9:35
  • 1
    Cause I need a call back as reference thats why. useRef does not provide a callback Commented Aug 7, 2020 at 9:39
  • 1
    It's inferred from initial, which is of type null. Commented Aug 7, 2020 at 10:08
  • How does setArrowElement look like? Commented Aug 7, 2020 at 17:26

1 Answer 1

27

You can fix this by typing your useState function:

const [refElement, setReference] = useState<HTMLDivElement | null>(null);

...

<div ref={setReference} />
Sign up to request clarification or add additional context in comments.

1 Comment

You can make this more flexible by using HTMLElement instead of HTMLDivElement - that way it will work with any element.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.