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

React中如何在input输入框下方追加表单校验错误提示信息

表单校验实现方案

核心改造思路

  • 新增errors状态存储各字段错误信息,初始为空,避免页面加载时默认显示错误
  • 抽离独立校验函数,统一维护校验规则,可复用在任意校验场景
  • 提交时触发校验,有错误则更新状态显示对应提示,无错误才执行提交逻辑
  • 输入时同步清空对应字段的错误提示,优化交互体验

改造后完整代码

import { useState } from "react";
    
function App() {
    const [enteredName, setEnteredName] = useState("");
    const [enteredAge, setEnteredAge] = useState("");
    const [submittedUsers, setSubmittedUsers] = useState([]);
    // 新增错误状态,存储各字段错误信息
    const [errors, setErrors] = useState({});

    // 独立封装的校验函数,接收姓名、年龄参数,返回错误对象
    const validateForm = (name, age) => {
        const errors = {};
        if (name.trim().length === 0) {
            errors.name = "Please enter your first name";
        }
        if (age.trim().length === 0) {
            errors.age = "Please enter a valid age";
        } else if (+age < 0) {
            errors.age = "Age must be greater than 0";
        }
        return errors;
    };

    const nameChangeHandler = (event) => {
        setEnteredName(event.target.value);
        // 输入时清空对应字段的错误
        if (errors.name) {
            setErrors(prev => ({...prev, name: undefined}));
        }
    };
    const ageChangeHandler = (event) => {
        setEnteredAge(event.target.value);
        // 输入时清空对应字段的错误
        if (errors.age) {
            setErrors(prev => ({...prev, age: undefined}));
        }
    };

    const submittedHandler = (event) => {
        event.preventDefault();
        // 执行校验
        const validateResult = validateForm(enteredName, enteredAge);
        // 有错误则更新错误状态,终止提交
        if (Object.keys(validateResult).length > 0) {
            setErrors(validateResult);
            return;
        }

        // 无错误走提交逻辑
        setSubmittedUsers([
            ...submittedUsers,
            {
                name: enteredName,
                age: enteredAge,
                id: Math.random().toString()
            },
        ]);
        // 提交成功后清空所有状态
        setEnteredName("");
        setEnteredAge("");
        setErrors({});
    };

    return (
        <div className="App">
            <header className="App-header">
                <h3>
                    <ul>
                        <li>Display user input </li>
                        <li>Validate user input</li>
                    </ul>
                </h3>

                <form onSubmit={submittedHandler}>
                    <input
                        placeholder="your name"
                        value={enteredName}
                        type="text"
                        onChange={nameChangeHandler}
                    />
                    <br />
                    {/* 读取对应字段的错误信息显示 */}
                    {errors.name && <span>error msg: {errors.name}</span>}
                    <br />
                    <br />

                    <input
                        placeholder="your age (number > 0)"
                        type="number"
                        value={enteredAge}
                        onChange={ageChangeHandler}
                    />
                    <br />
                    {/* 读取对应字段的错误信息显示 */}
                    {errors.age && <span> error msg: {errors.age}</span>}
                    <br />
                    <button>Submit</button>

                    <h3>
                        User input:
                        <ul>
                            {submittedUsers.map((u) => (
                                <li key={u.id}>
                                    {u.name} ({u.age} years old)
                                </li>
                            ))}
                        </ul>
                    </h3>
                </form>
            </header>
        </div>
    );
}

export default App;

逻辑说明

  • 初始状态下errors为空对象,所有错误提示默认隐藏,解决了方案1初始加载就显示错误的问题
  • 提交时校验不通过的错误信息会直接写入errors对应字段,模板中直接读取字段值即可在对应输入框下方显示错误,解决了方案2错误提示无法挂载的问题
  • 校验逻辑完全抽离为独立函数,后续修改规则只需要改validateForm内部逻辑即可,不会导致模板代码冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:24:06