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

React动态输入表单必填校验后无法匹配展示对应报错的问题

解决方案

核心修改点

  • 渲染动态输入项时,通过当前遍历索引i从formError数组中取出对应行的错误信息,在对应输入框下方展示,使用可选链避免未提交时读取空数组报错
  • 新增、删除输入项时同步更新formError数组,保证两个数组索引始终一一对应,避免错误提示错位
  • 增加输入时自动清除对应字段错误的逻辑,优化使用体验
  • 补全列表渲染的key属性,符合React语法规范

完整修改后代码

import React, { useState } from "react";
import "./styles.css";

function App() {
  const [inputList, setInputList] = useState([{ firstName: "", lastName: "" }]);
  const [formError, setFormError] = useState([{errorfirstName: "", errorlastName: ""}]);
  const [isSubmit, setisSubmit] = useState(false);

  // 处理输入变更
  const handleInputChange = (e, index) => {
    const { name, value } = e.target;
    const list = [...inputList];
    list[index][name] = value;
    setInputList(list);
    // 输入时清除对应字段的错误提示
    if (formError[index]) {
      const newError = [...formError];
      if (name === "firstName") newError[index].errorfirstName = "";
      if (name === "lastName") newError[index].errorlastName = "";
      setFormError(newError);
    }
  };

  // 处理移除按钮点击事件
  const handleRemoveClick = (index) => {
    const list = [...inputList];
    list.splice(index, 1);
    setInputList(list);
    // 同步删除对应索引的错误
    const newError = [...formError];
    newError.splice(index, 1);
    setFormError(newError);
  };

  // 处理添加按钮点击事件
  const handleAddClick = () => {
    setInputList([...inputList, { firstName: "", lastName: "" }]);
    // 同步添加对应空错误对象
    setFormError([...formError, {errorfirstName: "", errorlastName: ""}]);
  };
  const Submit = (e) => {
    e.preventDefault();
    const errorMsg = inputList.map((list, key) => {
      let error = {};
      if (!list.firstName) {
        error.errorfirstName = "FirstName is required";
      } else {
        error.errorfirstName = "";
      }
      if (!list.lastName) {
        error.errorlastName = "LastName is required";
      } else {
        error.errorlastName = "";
      }
      return error;
    });
    setFormError(errorMsg);
  };

  return (
    <div className="App">
      {inputList.map((x, i) => {
        return (
          <div className="box" key={i}>
            <div>
              <input
                name="firstName"
                placeholder="Enter First Name"
                value={x.firstName}
                onChange={(e) => handleInputChange(e, i)}
              />
              {formError[i]?.errorfirstName && (
                <p style={{color: 'red', margin: '4px 0 12px', fontSize: '12px'}}>{formError[i].errorfirstName}</p>
              )}
            </div>
            <div className="ml10">
              <input
                name="lastName"
                placeholder="Enter Last Name"
                value={x.lastName}
                onChange={(e) => handleInputChange(e, i)}
              />
              {formError[i]?.errorlastName && (
                <p style={{color: 'red', margin: '4px 0 12px', fontSize: '12px'}}>{formError[i].errorlastName}</p>
              )}
            </div>
            <div className="btn-box">
              {inputList.length !== 1 && (
                <button className="mr10" onClick={() => handleRemoveClick(i)}>
                  Remove
                </button>
              )}
              {inputList.length - 1 === i && (
                <button onClick={handleAddClick}>Add</button>
              )}
            </div>
          </div>
        );
      })}
      <button onClick={Submit}>Submit</button>
      <div style={{ marginTop: 20 }}>{JSON.stringify(inputList)}</div>
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:54:06