如何知道表单输入是否为空(React Hooks)

How to know if form input is empty (React Hooks)

我有一个表单,我想知道在提交时输入值是否为空,它们不会被发送。我试图通过 handleInputChange 的 if 来完成它,但这不起作用:

const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
        if ((e.target as HTMLInputElement).value) {
            setNewPost({
                ...newPost,
                [(e.target as HTMLInputElement).name]: (e.target as HTMLInputElement).value
            })
        }
        e.preventDefault();
    };

全部代码:

const New: React.FC = () => {
    // const [newPost, setNewPost] = useState("");
    const [newPost, setNewPost] = useState({
        title: '',
        author: '',
        content: ''
    })


    const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
        if ((e.target as HTMLInputElement).value) {
            setNewPost({
                ...newPost,
                [(e.target as HTMLInputElement).name]: (e.target as HTMLInputElement).value
            })
        }
        e.preventDefault();
    };

const createPost = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault(); //Detiene el formulario para que no actualize la página
    setPost(newPost)
}



return (
    <div className="containerHomepage">
        <form className="formulari" onSubmit={createPost}>
            <div className="containerBreadCrumb">
                <ul className="breadCrumb">
                    <li>Posts</li>
                </ul>
            </div>

            <div className="containerTitleButton">
                <input
                    className=""
                    type="text"
                    placeholder='Post title'
                    name="title"
                    onChange={handleInputChange}
                ></input>
                <button
                    className="button"
                    type="submit"
                >Save</button>
            </div>

            <div className="containerEdit">
                <input
                    className=""
                    type="text"
                    placeholder='Author'
                    name="author"
                    onChange={handleInputChange}
                ></input>
                <input
                    className=""
                    type="text"
                    placeholder='Content'
                    name="content"
                    onChange={handleInputChange}
                ></input>
            </div>

        </form>
    </div>
);
};


// ========================================

export default New;

您可以像这样将您的输入值与空字符串进行比较:

inputValue === ''

或字符串的大小:

inputValue.length === 0

并在您的提交中检查 if 语句中的值。

尝试提交时,首先需要检查输入值是否存在。为此,您检查每个输入值是否等于空字符串。

为了获得更好的可视化效果,请创建对此负责的变量:

const isValid = newPost.title !== '' && newPost.author !== '' && newPost.content !== ''

现在,如果 isValid 为真,我们提交表单,否则,我们不提交。

const createPost = (e) => {
    e.preventDefault()
    if (isValid) {
        // make api request
    } else {
        // handle empty fields
    }
}

您可以验证 createPost 中的空字段,它应该类似于:

 const createPost = (e: React.FormEvent<HTMLFormElement>) => {
     e.preventDefault(); //stop the form from reloading the page
        if (!newPost.title || !newPost.author || !newPost.content) {
           //show some error message
        } else {
           //perform further action
           setPost(newPost);
        }
    }

完整的工作示例click here

您当前的 handleInputChange 使得用户无法将任何输入更改为空字符串。 这里有一个主要的可用性缺陷。一旦用户键入第一个字符,他们就无法删除它! 您应该允许输入为空,但除非填写所有字段,否则不允许提交表单。

您可以使用 e.currentTarget 而不是 e.target 来避免大量类型断言。有更多信息 in this question,但这里重要的是 e.currentTarget 永远是 HTMLInputElement.

const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
  setNewPost({
    ...newPost,
    [e.currentTarget.name]: e.currentTarget.value
  });
};

@rax 的回答是正确的,但我会沿着这条路走得更远。


在任何时间点,你可以通过查看newPost的当前状态来知道表单是否有效。有很多方法可以写这个,它们都做同样的事情:

const isValid = Boolean(newPost.title && newPost.author && newPost.content);

使用类型强制。除空字符串外,所有字符串都是 truthy

const isValid = newPost.title !== '' && newPost.author !== '' && newPost.content !== '';

来自@Vladimir Trotsenko 的回答。

const isValid = Object.values(newPost).every(value => value.length > 0)

遍历 newPost 的所有值,因此如果您添加额外的字段,则无需更改任何内容。


您可以使用此 isValid 变量有条件地禁用“保存”按钮。

<button type="submit" disabled={!isValid}>Save</button>

您还可以使用 isValid 向用户显示消息或其他可见的反馈。例如,您可以在将鼠标悬停在禁用的按钮上时显示一条消息,告诉他们它被禁用的原因。

<button
  type="submit"
  disabled={!isValid}
  title={isValid ? "Create your post" : "All fields must be filled out."}
>
  Save
</button>

为了安全起见,我正在检查 createPost 函数中的 if (isValid),但我认为这实际上不是必需的,因为不会提交表单(即使点击输入)如果禁用提交按钮。

const createPost = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault(); // stop the form from reloading the page.
  if (isValid) {
    // put your actual code here instead.
    alert("submit success");
  }
};

完整代码:

import React, { useState } from "react";

const New: React.FC = () => {
  const initialState = {
    title: "",
    author: "",
    content: ""
  };
  const [newPost, setNewPost] = useState(initialState);

  const isValid = Boolean(newPost.title && newPost.author && newPost.content);

  const handleInputChange = (e: React.FormEvent<HTMLInputElement>) => {
    setNewPost({
      ...newPost,
      [e.currentTarget.name]: e.currentTarget.value
    });
  };

  const createPost = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault(); //stop the form from reloading the page
    if (isValid) {
      alert("submit success");
    }
  };

  return (
    <div className="containerHomepage">
      <form className="formulari" onSubmit={createPost}>
        <div className="containerBreadCrumb">
          <ul className="breadCrumb">
            <li>Posts</li>
          </ul>
        </div>

        <div className="containerTitleButton">
          <input
            className=""
            type="text"
            placeholder="Post title"
            name="title"
            onChange={handleInputChange}
            value={newPost.title}
          />

          <button
            className="button"
            type="submit"
            disabled={!isValid}
            title={
              isValid ? "Create your post" : "All fields must be filled out."
            }
          >
            Save
          </button>
        </div>

        <div className="containerEdit">
          <input
            className=""
            type="text"
            placeholder="Author"
            name="author"
            onChange={handleInputChange}
            value={newPost.author}
          />
          <input
            className=""
            type="text"
            placeholder="Content"
            name="content"
            onChange={handleInputChange}
            value={newPost.content}
          />
        </div>
      </form>
    </div>
  );
};

export default New;

CodeSandbox