【问题标题】:I can't type the ref correctly using useRef hook in typescript我无法在 typescript 中使用 useRef 钩子正确输入 ref
【发布时间】:2021-05-09 14:45:15
【问题描述】:

我正在尝试将 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

最后,将 ref 输入为 any 不会出错。

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

【问题讨论】:

  • forwardRef&lt;HTMLInputElement, Props&gt;((props, ref) =&gt; {}) - 你能试试这个吗?
  • 我收到第二个错误:Property 'current' does not exist on type '((instance: HTMLInputElement | null) =&gt; void) | MutableRefObject&lt;HTMLInputElement | null&gt;'.
  • 这个问题解决了吗?

标签: reactjs typescript ref


【解决方案1】:

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

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

【讨论】:

  • 感谢@Konstantin,但我看到我的代码和你的代码之间有两个区别。 1)我的 ref 被传递给子组件,我找不到 ref 道具的正确类型(通过 forwardRef 传递)。使用any 它可以工作,但当我尝试正确输入时却不行。 2) ref?.current?.focus() 不是已经是空检查了吗?但是,我尝试使用常规 if 语句,但它也不起作用
  • @eakl 是的,有区别。由于某种原因 ref 不是 InputText 组件的强制属性,尽管我们正确键入了 forwardRef。我想,这就是 forwardRef 的工作方式......检查一下:如果你不将 inputRef 传递给 InputText 打字稿不会抱怨任何事情。因此它在 InputText 中可能为空。另一方面,您可以在创建它的父组件中调用 inputRef。本文medium.com/@martin_hotell/…中的所有示例都有相同的模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-09
  • 2021-09-28
  • 2020-12-30
  • 2023-03-26
  • 1970-01-01
  • 2021-05-05
  • 2020-12-18
相关资源
最近更新 更多