reactjs 如何使用onSubmit输入表单组件?

dgiusagp  于 2023-01-02  发布在  React
关注(0)|答案(6)|浏览(133)

我有自己的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 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; }'.
62lalag4

62lalag41#

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

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

qni6mghb2#

你需要指定表单元素的类型,比如在表单中你有一个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中的elements属性。

interface FormElements extends HTMLFormControlsCollection {
    yourInputName: HTMLInputElement
}

interface YourFormElement extends HTMLFormElement {
   readonly elements: FormElements
}

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

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

现在您可以访问字段的值,并且typescript将知道它是什么

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

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

axkjgtzd

axkjgtzd3#

const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
cvxl0en2

cvxl0en24#

你的 prop 名称有个错误。你看到错配了吗?

const Form: React.FC<any> = ({ children, handleFormSubmit }) => (
<Form onSubmit={handleFormSubmit}>
    • 您的Form组件接受名为handleFormSubmit的属性,但您使用名为onSubmit的属性调用它。**

您需要更改其中一个位置的名称以使它们匹配,或者调用<Form handleFormSubmit={handleFormSubmit}>,或者更改Form组件的props以使prop命名为onSubmit
下面是如果将prop重命名为onSubmit并为其指定正确的类型而不是any时的外观。

interface FormProps {
    onSubmit: React.FormEventHandler;
}

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

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

sycxhyv7

sycxhyv75#

正如Ivo所写的,但如果您想正确地使用type键入它:

type FormElements = Readonly<
  {
    yourInputName: HTMLInputElement
  } & HTMLFormControlsCollection
>;

type YourFormElement = Readonly<
  {
    elements: FormElements;
  } & HTMLFormElement
>;
qnzebej0

qnzebej06#

如果您在React中有不受控制表单(我使用了MUI字段):

<form onSubmit={handleSubmit}>
          <TextField
            error={isError}
            helperText={isError ? 'Incorrect entry.' : ''}
            margin="normal"
            color="success"
            label="Name and surname"
            id="nameSurname"
            size="small"
          /></form>

你可以这样做:

const handleSubmit = (e: SyntheticEvent) => {
e.preventDefault();
const target = e.target as typeof e.target & {
  nameSurname: { value: string };
  //password: { value: string };
};
const nameSurname = target.nameSurname.value;
console.log(`nameSurname`, nameSurname);

};灵感源自here

相关问题