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

Next.js表单验证:用React Toastify展示提交成功与错误提示

解决方案

1. 确认依赖与导入

先安装react-toastify依赖:

npm install react-toastify
# 或
yarn add react-toastify

在组件文件顶部导入必要模块和样式:

import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

2. 完善表单校验规则

把minLength等校验逻辑移入register的配置项,为不同错误类型设置专属提示:

// name字段配置
{...register('name', {
  required: '姓名不能为空',
  minLength: {
    value: 3,
    message: '姓名长度不能少于3位'
  }
})}

// comment字段配置
{...register('comment', {
  required: '评论不能为空',
  minLength: {
    value: 5,
    message: '评论长度不能少于5位'
  }
})}

3. 处理提交与Toast提示逻辑

修改onSubmit函数处理API请求结果,同时监听表单错误触发对应Toast:

function Form({ _id }) {
    const {
        register,
        handleSubmit,
        formState: { errors },
        reset // 可选:用于提交成功后重置表单
    } = useForm();

    // 监听字段错误,触发Toast提示
    useEffect(() => {
        if (errors.name) toast.error(errors.name.message);
        if (errors.comment) toast.error(errors.comment.message);
    }, [errors]);

    const onSubmit = async (data) => {
        try {
            const res = await fetch('/api/CreateComment', {
                method: "POST",
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ ...data, _id })
            });

            if (res.ok) {
                toast.success('评论提交成功!');
                reset(); // 提交成功后重置表单(可选)
            } else {
                toast.error('提交失败,请稍后重试');
            }
        } catch (err) {
            toast.error('网络错误,请检查连接');
        }
    }

    return (<>
        <ToastContainer
            position="top-right"
            autoClose={5000}
            hideProgressBar={false}
            newestOnTop={false}
            closeOnClick
            rtl={false}
            pauseOnFocusLoss
            draggable
            pauseOnHover
        />
        <form id='my-form' onSubmit={handleSubmit(onSubmit)}>
            <div data-aos='fade-right' data-aos-delay='100' className="overflow-hidden mt-8 mb-4 w-[90vh] mx-auto bg-gray-100 rounded-lg border border-gray-300 dark:bg-gray-700 dark:border-gray-600">
                <label htmlFor="name" className="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"></label>
                <input 
                    {...register('name', {
                        required: '姓名不能为空',
                        minLength: { value: 3, message: '姓名长度不能少于3位' }
                    })} 
                    type="text" 
                    id="name" 
                    className="mb-2 radius block p-2 w-full text-gray-900 bg-gray-50 rounded-lg border-gray-300 sm:text-xs dark:bg-gray-800 dark:placeholder-gray-400 dark:text-white" 
                    placeholder="Your Name" 
                />
                {errors.name && <p className='text32'>{errors.name.message}</p>}
                <div className="py-2 px-4 bg-white rounded-t-lg dark:bg-gray-800" >
                    <label htmlFor="comment" className="sr-only">Your comment</label>
                    <textarea 
                        {...register('comment', {
                            required: '评论不能为空',
                            minLength: { value: 5, message: '评论长度不能少于5位' }
                        })} 
                        id="comment" 
                        rows="4" 
                        className="px-0 w-full text-sm  text-gray-900 bg-white border-0 dark:bg-gray-800 focus:ring-0 dark:text-white dark:placeholder-gray-400" 
                        placeholder="Write a comment..."
                    ></textarea>
                    {errors.comment && <p className='text32'>{errors.comment.message}</p>}
                </div>
                <div className="flex justify-between items-center py-2 px-3 border-t dark:border-gray-600">
                    <button type="submit" data-aos='fade-up' data-aos-delay='400' className="btnz inline-flex items-center py-2.5 px-4 text-xs font-medium text-center text-white bg-blue-700 rounded-lg focus:ring-4 focus:ring-blue-200 dark:focus:ring-blue-900 hover:bg-blue-800">
                        Post comment
                    </button>
                </div>
            </div>
        </form>
        <p data-aos='fade-left' data-aos-delay='700' className="h-[8vh] w-[70vh] m-auto text-xs text-gray-500 dark:text-gray-400">Remember, contributions to this topic should follow our <a href="#" className="text-blue-600 dark:text-blue-500 hover:underline">Community Guidelines</a>.</p>
    </>);
}

关键改动说明

  • 校验规则修正:把minLength从标签属性移至register配置,确保react-hook-form能正确识别并返回对应错误消息
  • Toast触发逻辑:用useEffect监听errors变化,字段校验失败时自动弹出错误Toast;在onSubmit中处理API请求结果,触发成功/失败提示
  • 请求优化:添加Content-Type请求头,确保后端正确解析JSON数据;用async/await简化异步逻辑
  • 无效代码清理:删除未定义的notify函数绑定,避免控制台报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:03:36