如何使用 onSubmit 键入表单组件?

Posted

技术标签:

【中文标题】如何使用 onSubmit 键入表单组件?【英文标题】:How to type a Form component with onSubmit? 【发布时间】:2019-10-12 19:53:30 【问题描述】:

我有自己的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&lt;HTMLFormElement&gt;) 中获取类型。

但是没有

我尝试构建一个界面,甚至使用any 类型:

interface FormProps 
  handleFormSubmit: any

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

但它给出了以下错误:

const Form: React.FunctionComponent<FormProps>
Type ' children: Element; onSubmit: (event: FormEvent<HTMLFormElement>) => void; ' is not assignable to type 'IntrinsicAttributes & FormProps &  children?: ReactNode; '.
  Property 'onSubmit' does not exist on type 'IntrinsicAttributes & FormProps &  children?: ReactNode; '.

【问题讨论】:

【参考方案1】:

这对我有用。只是根据你的猜测猜测。谢谢!

handlePostForm = (e: React.FormEvent) => 

【讨论】:

这种方法的一个问题是。它不会让你破坏来自e.target的道具 你会更了解我,我只是碰巧在一本书中读到了这个,并以此为基础进行了回答。但最后我不认为作者真的很擅长,因为示例策略在功能上留下了真正的问题。【参考方案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 界面中指定的那样。

【讨论】:

【参考方案3】:

您的道具名称有误。你看到不匹配了吗?

const Form: React.FC<any> = ( children, handleFormSubmit ) => (
<Form onSubmit=handleFormSubmit>

您的 Form 组件采用名为 handleFormSubmit 的道具,但您使用名为 onSubmit 的道具调用它。

您需要更改其中一个位置的名称,以便它们都匹配。要么调用&lt;Form handleFormSubmit=handleFormSubmit&gt;,要么更改Form组件的props,使props命名为onSubmit


如果您将 prop 重命名为 onSubmit 并给它一个正确的类型而不是 any,它应该是这样的。

interface FormProps 
    onSubmit: React.FormEventHandler;


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

如果您像这样定义Form,则无需对ParentComponent 进行任何更改。

【讨论】:

【参考方案4】:
const validateForm = (e: React.FormEvent<HTMLFormElement>) => 
  e.preventDefault();
  // do your validation below...
;

【讨论】:

这个问题已经包含了一段非常相似的代码:如果你不给出解释,这是没有帮助的。 您的答案可以通过额外的支持信息得到改进。请“编辑”以添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到更多关于如何写好答案的信息:***.com/help/how-to-answer

以上是关于如何使用 onSubmit 键入表单组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从父组件 OnSubmit Angular 4 触发对子组件的验证?

使用 react 和 EmailJs 在表单中通过 onSubmit 传递第二个参数

Material UI 的 React 评分组件是如何在表单中使用的?

如何在使用表单组件时在 apollo-client 中链接突变

ASP中,onsubmit该如何使用?为啥我设置后,form表单中要执行的onsubmit没效果呢?

如何在 onSubmit 事件中使用 react-query useQuery?