如何使用onSubmit键入(打字稿)表单组件?

时间:2019-05-27 08:51:33

标签: reactjs typescript typescript-typings

我有自己的Form组件,希望与Parent Component分开。

const Form: React.FC<any> = ({ children, handleFormSubmit }) => (
  <form onSubmit={handleFormSubmit}>{children}</form>
);

Parent Component

const ParentComponent = () => {
...

const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    publishReview(review).then(() => setReview(initialReviewState));
  };

return (
 <Form onSubmit={handleFormSubmit}>
...
</Form>
)}

我认为handleFormSubmit将从声明const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>)中获取类型。

但不是

我试图构建一个接口,甚至使用any类型:

interface FormProps {
  handleFormSubmit: any
}
const Form: React.FC<FormProps>= ({ children, handleFormSubmit }) => (
  <form onSubmit={handleFormSubmit}>{children}</form>
);

但是它给出了以下错误:

const形式:React.FunctionComponent 类型'{children:Element; onSubmit:(event:FormEvent)=>无效; }'不能分配给'IntrinsicAttributes&FormProps&{children ?: ReactNode; }'。   属性'onSubmit'在类型'IntrinsicAttributes&FormProps&{children ?: ReactNode; }'。


3 个答案:

答案 0 :(得分:2)

您需要指定表单元素的类型。例如,假设在您的表单中有一个 ID 为 yourInputName 的输入:

<form onSubmit={handleSubmit}>
  <div>
    <label htmlFor="yourInputName">Username:</label>
    <input id="yourInputName" type="text" />
  </div>
  <button type="submit">Submit</button>
</form>

在您的 handleSubmit 中,您需要指定 event.currentTarget 的类型。表单标签的类型为 HTMLFormElement,属性为 elements,其类型为 HTMLFormControlsCollection,但我们可以覆盖它以告诉 TS 我们的输入是什么。创建一个扩展 HTMLFormControlsCollection 的接口,指定字段的类型,然后使用自定义接口覆盖 HTMLFormElement 中的元素属性。

interface FormElements extends HTMLFormControlsCollection {
    yourInputName: HTMLInputElement
}

interface YourFormElement extends HTMLFormElement {
   readonly elements: FormElements
}

然后将新类型传递给处理函数

const handleFormSubmit = (e: React.FormEvent<YourFormElement>) => {}

您现在可以访问字段的值,打字稿就会知道它是什么

const handleFormSubmit = (e: React.FormEvent<YourFormElement>) => {
    e.preventDefault();
    console.log(e.currentTarget.elements.yourInputName.value)
}

如果您将鼠标悬停在 value 上,TS 应向您显示一条消息,表明数据类型为 HTMLInputElement.value: string,正如您在 FormElements 界面中指定的那样。

答案 1 :(得分:0)

问题是您正尝试使用名为onSubmit的道具传递事件处理程序,而组件希望使用名为handleFormSubmit的道具

所以您应该:

以这种方式使用Form<Form handleFormSubmit={handleFormSubmit}>

或将其定义更改为以下内容:

const Form: React.FC<FormProps>= ({ children, onSubmit }) => (
  <form onSubmit={onSubmit}>{children}</form>
);

具有以下界面:

interface FormProps {
  onSubmit: any
}

答案 2 :(得分:0)

这对我有用。只是根据您的猜测进行猜测。谢谢!

handlePostForm = (e: React.FormEvent) => {