按多个级别转发参考[Typescript/Rect]



我正在努力遵循原子设计原则,但我不确定我做得是否正确。我创建了三个组件:Form、ExpandableInput和Input。Input是HTML输入包装器,Expandable输入是带下拉框的Input,Form只是表单。我想从Form组件访问当前输入值,所以我正在进行多级引用转发。Form组件中的一切都很好,但问题是我必须在ExpandableInput组件中使用ref.current.value,但我收到了以下错误。

类型"上不存在属性"current"((实例:HTMLInputElement|null(=>void(|MutableRefObject<HTML输入元素|null>'。类型"上不存在属性"current"(实例:HTMLInputElement|null(=>void。

我不知道如何告诉typescript ExpandableInput中的ref变量的类型为ref,并且不是null。我不知道多个级别的ref转发是否是一种好的做法,也许有更好的方法来获得输入值。

示例代码:AddForm

const Form = () => {
// Refs
const caRef = useRef<HTMLInputElement>(null);
return (
<FormTemplate >
<ExpandableInput
option={CompetenceAreaOption}
ref={caRef}
/>
</FormTemplate>
);
}
export default AddForm;

可扩展输入

const ExpandableInput = React.forwardRef<HTMLInputElement, IProps>((
props,
ref
): JSX.Element => {
const pickInputValue = (value: string): void => {
console.log(ref.current) // Error
console.log(ref) // Input reference
}
}
return (
<div>
<div>
<Input
ref={ref}
/>
</div>             
</div>
);
})
export default ExpandableInput;      

输入

const Input = React.forwardRef<HTMLInputElement, IProps>(({
props,
ref
): JSX.Element => {

return (
<input
ref={ref}
/>
);
})

export default Input;

forwardRef接收到的ref实际上有三个可能的值。

type ForwardedRef<T> = ((instance: T | null) => void) | MutableRefObject<T | null> | null;

它可以是null。它可以是您所期望的,它是由useRef创建的MutableRefObject。第三种可能性是它可以是一个回调函数。(注意:forwardRef不支持传统的string引用(。

这三个人中的任何一个都可以晋级下一个级别。但如果我们想访问ref.current,那么我们需要确保我们拥有的是MutableRefObject。我们使用类型保护:if ( ref && "current" in ref)来完成此操作。这样就可以访问ref.current

ref.current可能是null(当ref还没有附加到DOM时(。因此,我们还需要检查current是否与if或可选的链式运算符?.有效

简称:

if ( ref && "current" in ref) {
ref.current?.focus();
}

长版本:

// make sure that ref is a MutableRefObject
if (ref && "current" in ref) {
// input has type HTMLInputElement | null
const input = ref.current;
// exlude null current value
if (input) {
// now we know that we have an input
input.focus();
}
}

打字游戏场链接

最新更新