[英]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.