繁体   English   中英

将反应回调引用与转发引用一起使用

[英]Using react callback ref with forwarded ref

我有一个必须支持不确定状态的 Checkbox 反应组件,但我正在更新我们的组件以正确转发引用。 复选框组件已经在内部使用回调引用来设置不确定属性。 这是原始组件(简化):

export type ICheckboxProps = {
  checked?: boolean
  indeterminate?: boolean
} & React.InputHTMLAttributes<HTMLInputElement>

export const Checkbox: React.FC<ICheckboxProps> = props => {
  const { checked = false, ...rest } = props;
  return (
    <input
      type="checkbox"
      checked={checked}
      ref={ref => {
        if (ref) {
          ref.indeterminate = !checked ? indeterminate! : false;
        }
      }}
      {...rest}
    />
  )
}

现在,由于这是一个 UI 库,我也尝试转发一个 ref。 但这与回调引用发生冲突 - 现在我有两个单独的引用。 此外,转发的引用可以是回调引用。 所以我什至无法访问那里的实例来设置不确定的属性。 我尝试了很多东西,但无论我做什么,打字稿有用的红色下划线告诉我我错了。

如何将转发的引用应用于输入并在输入上设置不确定属性?

这是大部分方式,但有一个问题指出:

export type ICheckboxProps = {
  checked?: boolean
  indeterminate?: boolean
} & React.InputHTMLAttributes<HTMLInputElement>

export const Checkbox = React.forwardRef<HTMLInputElement, ICheckboxProps>((props, inRef) => {
  const { checked = false, ...rest } = props;
  return (
    <input
      type="checkbox"
      checked={checked}
      ref={ref => {
        if (ref) {
          ref.indeterminate = !checked ? indeterminate! : false;
          if (inRef) {
            if (typeof inRef === "function") {
              inRef(ref)
            } else {
              inRef.current = ref // Cannot assign to 'current' because it is a read-only property.
            }
          }
        }
      }}
      {...rest}
    />
  )
})

useImperativeHandle钩子与您的第二个示例几乎完全相同。 然后将ref.current分配给inRef由 React 内部处理,您不必通过更改 readonly 属性来破坏合同。

export const Checkbox = React.forwardRef<HTMLInputElement, ICheckboxProps>((props, inRef) => {
  const { checked = false, indeterminate, ...rest } = props;

  const ref = useRef<HTMLInputElement>(null)
  useImperativeHandle(inRef, () => ref.current!, [ref])

  return (
    <input
      type="checkbox"
      checked={checked}
      ref={ref}
      {...rest}
    />
  )
})

在打字稿游乐场

我想对ref.current上的非空断言发表评论。 据我所知,孩子的 refs 在父母的 refs 之前被解析,但我能找到的文档中唯一相关的语句是调用inputRef.current.focus()useImperativeHandle文档中没有空保护

你可以对转发的 ref 做任何你想做的事情,包括设置它的当前值:

const Checkbox = React.forwardRef(({ checked = false, indeterminate, ...rest }, forwardedRef) => (
  <input
    type="checkbox"
    checked={checked}
    ref={(inputElement) => {
      if (inputElement) {
        inputElement.indeterminate = !checked && indeterminate
      }

      if (forwardedRef) {
        if(typeof(forwardedRef) !== "function") {
          forwardedRef(inputElement)
      } else {
        forwardedRef.current = inputElement
      }
    }
    {...rest}
  />
))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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