You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React表单提交后聚焦输入框时清除自定义错误消息方案咨询

问题解决思路与方案

要实现「聚焦输入框时清除对应错误信息」,同时解决「提交空表单后输入框失焦」的问题,可按以下步骤修改:

1. 实现通用的聚焦错误清除函数

创建一个接收字段名的通用函数,在聚焦时删除对应字段的错误信息:

const handleFocus = (fieldName) => {
  setFormErrors(prevErrors => {
    const updatedErrors = {...prevErrors};
    delete updatedErrors[fieldName];
    return updatedErrors;
  });
};

2. 给所有输入框绑定聚焦事件

给每个InputField组件传递onFocus属性,调用上述函数并传入对应字段名:

<InputField
  name="username"
  label="Username"
  error={formErrors.username}
  fieldRef={usernameField}
  onFocus={() => handleFocus('username')}
/>
<InputField
  name="email"
  label="Email address"
  error={formErrors.email}
  fieldRef={emailField}
  onFocus={() => handleFocus('email')}
/>
<InputField
  name="password"
  label="Password"
  type="password"
  error={formErrors.password}
  fieldRef={passwordField}
  onFocus={() => handleFocus('password')}
/>
<InputField
  name="password2"
  label="Password again"
  type="password"
  error={formErrors.password2}
  fieldRef={password2Field}
  onFocus={() => handleFocus('password2')}
/>

3. 修复提交后输入框失焦问题

在表单提交函数中,若存在错误信息,自动聚焦第一个有错误的输入框:

const onSubmit = async (event) => {
  event.preventDefault();
  const registerData = {
    username: usernameField.current.value.trim(),
    email: emailField.current.value.trim(),
    password: passwordField.current.value,
    password2: password2Field.current.value,
  };
  estadoErrores = validField(registerData);
  setFormErrors(estadoErrores["errores"]);

  // 自动聚焦第一个错误字段
  if (Object.keys(estadoErrores.errores).length > 0) {
    const firstErrorField = Object.keys(estadoErrores.errores)[0];
    switch(firstErrorField) {
      case 'username':
        usernameField.current.focus();
        break;
      case 'email':
        emailField.current.focus();
        break;
      case 'password':
        passwordField.current.focus();
        break;
      case 'password2':
        password2Field.current.focus();
        break;
      default:
        break;
    }
  }
};

4. 修正语法错误

原代码中onSubmit函数未闭合,需补充}将其与组件渲染代码分开。


修改后的完整RegistrationPage.js代码

import { useState, useEffect, useRef } from "react";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import InputField from "../components/InputField";
// other imports ...

const validField = (fields) => {
// Validate input fields and return errors
  const result = { estado: {}, errores: {} };
  const usrnm = fields.username === "";
  const email = fields.email === "";
  const pass1 = fields.password === "";
  const pass2 = fields.password2 !== fields.password;

  result["estado"]["username"] = usrnm;
  result["estado"]["email"] = email;
  result["estado"]["password"] = pass1;
  result["estado"]["password2"] = pass2;

  if (usrnm) {
    result["errores"]["username"] = "Username cannot be empty";
  }
  if (email) {
    result["errores"]["email"] = "Email cannot be empty";
  }
  if (pass1) {
    result["errores"]["password"] = "Password cannot be empty";
  }
  if (pass2) {
    result["errores"]["password2"] = "Password does not match";
  }
  return result;
};

export default function RegistrationPage() {
  const [formErrors, setFormErrors] = useState({});

  const usernameField = useRef();
  const emailField = useRef();
  const passwordField = useRef();
  const password2Field = useRef();
  let estadoErrores = {};

  useEffect(() => {
  // initial focus
    usernameField.current.focus();
  }, []);

  const handleFocus = (fieldName) => {
    setFormErrors(prevErrors => {
      const updatedErrors = {...prevErrors};
      delete updatedErrors[fieldName];
      return updatedErrors;
    });
  };

  const onSubmit = async (event) => {
    event.preventDefault();
    const registerData = {
      username: usernameField.current.value.trim(),
      email: emailField.current.value.trim(),
      password: passwordField.current.value,
      password2: password2Field.current.value,
    };
    estadoErrores = validField(registerData);
    setFormErrors(estadoErrores["errores"]);

    // 自动聚焦第一个错误字段
    if (Object.keys(estadoErrores.errores).length > 0) {
      const firstErrorField = Object.keys(estadoErrores.errores)[0];
      switch(firstErrorField) {
        case 'username':
          usernameField.current.focus();
          break;
        case 'email':
          emailField.current.focus();
          break;
        case 'password':
          passwordField.current.focus();
          break;
        case 'password2':
          password2Field.current.focus();
          break;
        default:
          break;
      }
    }
  };

  return (
    <Body>
      <h1>Register</h1>
      <Form onSubmit={onSubmit}>
        <InputField
          name="username"
          label="Username"
          error={formErrors.username}
          fieldRef={usernameField}
          onFocus={() => handleFocus('username')}
        />
        <InputField
          name="email"
          label="Email address"
          error={formErrors.email}
          fieldRef={emailField}
          onFocus={() => handleFocus('email')}
        />
        <InputField
          name="password"
          label="Password"
          type="password"
          error={formErrors.password}
          fieldRef={passwordField}
          onFocus={() => handleFocus('password')}
        />
        <InputField
          name="password2"
          label="Password again"
          type="password"
          error={formErrors.password2}
          fieldRef={password2Field}
          onFocus={() => handleFocus('password2')}
        />
        <Button variant="primary" type="submit">
          Register
        </Button>
      </Form>
    </Body>
  );
}

内容的提问来源于stack exchange,提问作者dannisis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 23:17:26