首页 > 解决方案 > 我无法在 typescript 中使用 useRef 钩子正确输入 ref

问题描述

我正在尝试将 ref 从父组件(EditableCell)传递给子组件(输入),并.current.focus在单击父组件时使用其属性。

我正在使用forwardRef打字稿的功能,但我无法正确输入

interface Props {
  // Some props type
}

const CellEditable = (props: Props) => {
  const [isEditing, setEditing] = useState<boolean>(false)
  const inputRef = useRef<HTMLInputElement>(null)

  const handleClick = () => setEditing(!isEditing)

  const opts = {
    ref: inputRef,
    value: props.value,
    onChange: props.onChange
  }

  return (
    <div onClick={handleClick}>
      {
        isEditing
        ? <InputText {...opts} />
        : <div>{props.value}</div>
      }
    </div>
  )
}
interface Props {
  // Some props type
}

type Ref = HTMLInputElement

const InputText = forwardRef((props: Props, ref: Ref) => {
  useEffect(() => {
    ref?.current?.focus()
  })
  
  return (
    <input
      type='text'
      ref={ref}
      value={props.value}
      onChange={props.onChange}
    />
  )
})

使用上面的代码,我收到以下错误:

Argument of type '(props: Props, ref: Ref) => JSX.Element' is not assignable to parameter of type 'ForwardRefRenderFunction<unknown, Props>'.
  Types of parameters 'ref' and 'ref' are incompatible.
    Type '((instance: unknown) => void) | MutableRefObject<unknown> | null' is not assignable to type 'HTMLInputElement'.
      Type 'null' is not assignable to type 'HTMLInputElement'.  TS2345

如果我forwardRed用泛型键入,我会得到另一种错误:

const InputText = forwardRef<Ref, Props>((props, ref) => { ... }
Property 'current' does not exist on type '((instance: HTMLInputElement | null) => void) | MutableRefObject<HTMLInputElement | null>'.
  Property 'current' does not exist on type '(instance: HTMLInputElement | null) => void'.  TS2339

最后,输入 refany没有错误。

我是 Typescript 的新手,我不明白上面提到的错误。

标签: reactjstypescriptref

解决方案


查看以下沙箱:https ://codesandbox.io/s/aged-night-3pwjs 。

TypeScript 警告您,您的 ref 可能为 null,因此任何带有 if 的代码ref.current都应该用 if 语句包装,这将确保它ref.current存在。


推荐阅读