简体   繁体   中英

How do I type a ref callback with useCallback (with Typescript)?

I'm new to Typescript and can't figure out how to type this situation. I'm writing a custom hook and trying to create a callback ref. My problem is that this function sets the ref's current , and returns nothing, but since I use it as a ref, typescript yells at me Property 'current' is missing in type '(node: any) => void' but required in type 'RefObject<HTMLDivElement>' .

Thank you in advance.

This is the code:

import React, {useCallback, useRef} from 'react'

const useCustom = (): [RefObject<HTMLDivElement>] => {
  const ref = useRef<HTMLDivElement | null>(null)
  const setRef = useCallback(node => {
    ....
    ref.current = node
  }, [])

  return [setRef]
}

const SomeComp = () => {
  const [ref] = useCustom()

  return <div ref={ref}>Text</div>
}

The problem is you said the return value of useCustom would be RefObject<HTMLDivElement> , but returned (node: HTMLDivElement) => void .

Your custom hook should return 2 values: one for setting the ref value, the other for the ref itself. So it will look like useState hook:

const useCustom = (): [
  RefObject<HTMLDivElement>,
  (node: HTMLDivElement) => void
] => {
  const ref = useRef<HTMLDivElement | null>(null);
  const setRef = useCallback((node) => {
    ref.current = node;
  }, []);

  return [ref, setRef];
};

I propose a different solution.

This is assuming the author is trying to use a "callback ref" to execute a side effect, when the ref changes. When using two return values the ref might still accidentally be set (by using the ref ) without executing the callback ( setRef ), which I'm guessing is not the author's intention.

Typing things like this seems to work as expected (using author's example):

import React, {useCallback, useRef} from 'react'

const useCustom = (): [React.RefCallback<HTMLElement>] => {
    const ref = useRef<HTMLElement | null>(null)
    const setRef: React.RefCallback<HTMLElement> = useCallback(node => {
    ....
    ref.current = node
  }, [])

  return [setRef]
}

const SomeComp = () => {
  const [ref] = useCustom()

  return <div ref={ref}>Text</div>
}

Note: I also changed HTMLDivElement to HTMLElement to make the hook more universal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM