在自定义输入元素上使用带有打字稿的 useRef

Posted

技术标签:

【中文标题】在自定义输入元素上使用带有打字稿的 useRef【英文标题】:useRef with typescript on custom input element 【发布时间】:2021-05-19 19:06:54 【问题描述】:

我正在努力在带有打字稿的input 上使用 useRef。我检查了许多链接,例如 this one,但我仍然遇到同样的错误。

const MainHeader: React.FC = () => 

const InputStyled = styled(Input)`
  // some basic css
`;

const searchElement = useRef<htmlInputElement>(null);

return (
  <>
    <InputStyled full ref=searchElement type="search" />
  </>
);


我的Input 组件:

export type SearchFieldProps = React.InputHTMLAttributes<HTMLInputElement> & 
  full?: boolean;
  medium?: boolean;
  light?: boolean;
;

const SearchField = styled.input<SearchFieldProps>`
  // css rules here
`;

const Input: React.FC<SearchFieldProps> = (props) => <SearchField ...props />;

export default Input;

我认为我在这里没有做任何异国情调的事情,但它会返回:

No overload matches this call.
  Overload 1 of 2, '(props: Pick<Pick<PropsWithChildren<SearchFieldProps>, "form" | "slot" | "style" | "title" | "pattern" | "type" | "name" | "defaultChecked" | ... 279 more ... | "light"> & Partial<...>, "form" | ... 286 more ... | "light"> &  ...;  &  ...; ): ReactElement<...>', gave the following error.
    Type ' ref: RefObject<HTMLInputElement>; full: true; placeholder: string | undefined; type: string; ' is not assignable to type 'IntrinsicAttributes & Pick<Pick<PropsWithChildren<SearchFieldProps>, "form" | "slot" | "style" | "title" | "pattern" | ... 282 more ... | "light"> & Partial<...>, "form" | ... 286 more ... | "light"> &  ...;  &  ...; '.
      Property 'ref' does not exist on type 'IntrinsicAttributes & Pick<Pick<PropsWithChildren<SearchFieldProps>, "form" | "slot" | "style" | "title" | "pattern" | ... 282 more ... | "light"> & Partial<...>, "form" | ... 286 more ... | "light"> &  ...;  &  ...; '.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<FC<SearchFieldProps>, any, , never, FC<SearchFieldProps>>): ReactElement<...>', gave the following error.
    Type ' ref: RefObject<HTMLInputElement>; full: true; placeholder: string | undefined; type: string; ' is not assignable to type 'IntrinsicAttributes & Pick<Pick<PropsWithChildren<SearchFieldProps>, "form" | "slot" | "style" | "title" | "pattern" | ... 282 more ... | "light"> & Partial<...>, "form" | ... 286 more ... | "light"> &  ...;  &  ...; '.
      Property 'ref' does not exist on type 'IntrinsicAttributes & Pick<Pick<PropsWithChildren<SearchFieldProps>, "form" | "slot" | "style" | "title" | "pattern" | ... 282 more ... | "light"> & Partial<...>, "form" | ... 286 more ... | "light"> &  ...;  &  ...; '.

欢迎任何想法/建议!

谢谢

【问题讨论】:

看起来它希望您的 InputStyled 组件声明 ref 属性。我没有使用样式组件,但也许您创建了一个包装器,在 ref 属性中添加并返回样式组件? 【参考方案1】:

您需要将 forwardRef 用于您的用例。您的 Input 组件应如下所示。

import React from "react";
import styled from "styled-components";

export type SearchFieldProps = React.InputHTMLAttributes<HTMLInputElement> & 
  full?: boolean;
  medium?: boolean;
  light?: boolean;
 
;

const SearchField = styled.input<SearchFieldProps>`
  // css rules here
`;

const Input = React.forwardRef<HTMLInputElement>((props, ref) => (
  <SearchField ...props ref=ref />
));

export default Input;

第二个解决方案

import React,  FC  from "react";
import styled from "styled-components";

export type SearchFieldProps = React.InputHTMLAttributes<HTMLInputElement> & 
  full?: boolean;
  medium?: boolean;
  light?: boolean;
  ref?: React.ForwardedRef<HTMLInputElement>;
;

const SearchField = styled.input<SearchFieldProps>`
  // css rules here
`;

const Input: FC<SearchFieldProps> = React.forwardRef((props, ref) => (
  <SearchField ...props ref=ref />
));

export default Input;

【讨论】:

嗨@johann,我为你添加了第二个解决方案,你需要在你的道具上添加一个 ref 道具。 感谢@Sam 的回复。尝试使用您的版本时,我有一个 Property 'light' does not exist on type 'IntrinsicAttributes &amp; RefAttributes&lt;HTMLInputElement&gt;' ..如果我将 HTMLInputElement 替换为 SearchFieldProps 结果是相同的,它将破坏另一个 Input 而没有定义 ref`。 谢谢@Sam。但是如何使它与没有 ref 属性的 I 一起工作?有可能吗?

以上是关于在自定义输入元素上使用带有打字稿的 useRef的主要内容,如果未能解决你的问题,请参考以下文章

使用带有打字稿的猫鼬创建自定义验证时出错

使用带有打字稿的猫鼬创建自定义验证时出错

带有打字稿的角度材料设计

带有打字稿的枚举

使用带有打字稿的 react-router

如何在带有打字稿的 vue.js 中使用 javascript 组件?