React js/Typescript 不使用onChange如何获取input标签onSubmit的值?

How to get the value of input tag onSubmit without using onChange in React js/Typescript?

我没有其他特殊的 onChange 事件,因此我需要通过仅处理专门针对 Form 标记的 onSubmit 事件来简化我的代码。

我正在 React 的 Typescript 中创建一个简单的 Form,当我单击 Submit 时,我想记录输入控制台中的框。但是当我这样做时出现错误。

import React from "react";

const handleSubmit =(event:React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    console.log(event.currentTarget[0].value);
  };

export const InputForm: React.FC  = () =>{
    return (
        <form className='form-container' onSubmit={handleSubmit}>
            <input className="input" placeholder="Enter value" required />
            <button type="submit">Enter</button>
          </form>  
      )
}

我对这一行的推理 => console.log(event.currentTarget[0].value); 是表单标签有 2 个元素,输入和按钮,所以 event.currentTarget[0] 单独 returns 控制台中的输入标签但是它当我尝试添加 .value

这里通常是使用受控组件,但您已经说过您不想那样做。

问题是 event.currentTarget[0] 只是类型 Element,而 Element 没有 value(这只是在某些元素上,例如 HTMLInputElement, HTMLSelectElement, 等等).

知道它是 Element 子类型 value,但 TypeScript 不知道,因为并非所有表单控件元素都具有 valuefieldsetobject 一开始没有,但它们被算作 form elements)。

您可以在您的工具包中加入一个实用断言函数:

function assertIsFormFieldElement(element: Element): asserts element is HTMLInputElement | HTMLSelectElement | HTMLButtonElement {
// Customize this list as necessary −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    if (!("value" in element)) {
        throw new Error(`Element is not a form field element`);
    }
}

...然后使用它:

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    const firstField = event.currentTarget[0];
    assertIsFormFieldElement(firstField);
    console.log(firstField.value);
};

Playground link


旁注:如果你打算这样做,你可以考虑在输入上放置一个 name 并在查找元素时使用它,而不是假设 input 将是第一个元素:

<input name="the-name" className="input" placeholder="Enter value" required />

然后您可以使用实用函数从表单中获取命名项:

function getFormControl(form: HTMLFormElement, name: string): HTMLInputElement | HTMLSelectElement | HTMLButtonElement /* | ...*/ {
    const control = form.elements.namedItem(name);
    if (!control || control instanceof RadioNodeList || !("value" in control)) {
        throw new Error(`Form control "${name}" not found or was a RadioNodeList`);
    }
    return control;
} 

// ...


const handleSubmit = (event: React.FormEvent<HTMLFormElement>) =>{
    event.preventDefault();
    const inputField = getFormControl(event.currentTarget, "the-name");
    console.log(inputField.value);
};

Playground link