首页 > 解决方案 > 如何优雅地处理 React 表单错误

问题描述

当您输入正确的登录名/密码时,我有一个登录表单。但是如果你输入了错误的登录信息,你会得到这个丑陋的错误信息

在此处输入图像描述

我试图通过设置一个formErrors状态来优雅地处理这个问题,然后在一个样式良好的警报消息中返回任何错误,但我不断收到你在屏幕截图中看到的错误TypeError: Cannot read property 'length' of undefined

听起来好像formErrors是未定义的,但我不明白为什么会这样。我做错了什么,我该如何解决这个问题?我会很感激任何帮助。

编辑:添加了来自 app.js 和 api.js 的 loginUser 函数的代码

UserLoginForm.js

function UserLoginForm({ loginUser }) {

  const [formData, setFormData] = useState({
    username: "",
    password: "",
  });
  const [formErrors, setFormErrors] = useState([]);
  const history = useHistory();

  console.debug(
    "UserLoginForm",
    "login=", typeof loginUser,
    "formData=", formData,
    "formErrors", formErrors,
);

  // Handle form submission 
  async function handleSubmit(evt) {
    evt.preventDefault();
    let results = await loginUser(formData);
    if (results.success) {
      history.push("/");
    } else {
      setFormErrors(results.errors);
    }
  }

  // Handle change function 
  function handleChange(evt) {
    const { name, value } = evt.target;
    setFormData(d => ({ ...d, [name]: value }));
  }

  return (
    <div className="container my-5">
      <div className="row">
        <div className="col-lg-2">

        </div>
        <div className="col-lg-10">
          <h1>User Login Form</h1>
          <div className="my-3">
            <form onSubmit={handleSubmit}>
              <div className="col-lg-9 my-2">
                <input
                  name="username"
                  className="form-control"
                  placeholder="Username"
                  value={formData.username}
                  onChange={handleChange}
                  required
                />
              </div>
              <div className="col-lg-9 my-2">
                <input
                  name="password"
                  className="form-control"
                  placeholder="Password"
                  type="password"
                  value={formData.password}
                  onChange={handleChange}
                  required
                />
              </div>

              {formErrors.length
                ? <Alert type="danger" messages={formErrors} />
                : null
              }

              <button className="btn btn-lg btn-primary my-3">
                Submit
              </button>
            </form>
          </div>
        </div>
        <div className="col-lg-2">

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

警报.js

function Alert({ type="danger", messages=[] }) {
  console.debug("Alert", "type=", type, "messages=", messages);
    return (
      <div className={`alert alert-${type}`} role="alert">
        {messages.map(error => (
          <p key={error} className="mb-0 small">
            {error}
          </p>
        ))}
      </div>
    );
}

应用程序.js

 async function loginUser(loginData) {
    try {
      let token = await VolunteerApi.loginUser(loginData);
      setToken(token);
      return {
        success: true
      };
    } catch (err) {
      console.error("Problem with the login function", err);
      return {
        success: false, err
      };
    }
  }

api.js

static async loginUser(data) {
    let res = await this.request(`auth/login-user`, data, "post");
    return res.token;
  }

标签: javascriptreactjs

解决方案


你的问题是你没有{errors}loginUser函数中返回。{err}相反,您正在返回,因此formErrors.length引发了错误,因为formErrors设置为未定义。

您需要确保返回您期望的内容。我在下面修改了它,虽然没有太多信息,但它会运行。

请注意,您可能必须将 API 返回的错误映射到字符串消息。

 async function loginUser(loginData) {
    try {
      let token = await VolunteerApi.loginUser(loginData);
      setToken(token);
      return {
        success: true
      };
    } catch (err) {
      console.error("Problem with the login function", err);
      return {
        success: false, errors: [err]
      };
    }
  }

推荐阅读