如何在react-final-form中设置数组字段的错误?求验证示例
没问题!我来帮你搞定react-final-form里数组字段的错误提示和验证规则设置~针对你提到的场景,我已经整理好了完整的实现方案,下面是具体内容:
数组字段验证与错误提示实现
1. 编写全局验证函数
首先我们需要定义一个验证函数,它会遍历数组中的每一项,为每个子字段添加对应的错误规则:
const validate = (values) => { const errors = {}; // 检查contacts数组是否存在 if (values.contacts) { errors.contacts = []; values.contacts.forEach((contact, index) => { const contactErrors = {}; // 姓名必填验证(去除首尾空格) if (!contact.name?.trim()) { contactErrors.name = "姓名不能为空"; } // 邮箱格式验证(有输入时才校验格式) if (contact.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(contact.email)) { contactErrors.email = "请输入有效的邮箱地址"; } // 如果当前项有错误,添加到errors数组对应索引位置 if (Object.keys(contactErrors).length > 0) { errors.contacts[index] = contactErrors; } }); } return errors; };
2. 为数组子字段添加错误提示
在FieldArray的渲染函数中,每个子字段(姓名、邮箱)需要通过meta.error获取对应错误,结合meta.touched判断是否显示错误提示(避免页面加载就显示错误,只有用户触碰过字段后才展示):
<FieldArray name="contacts"> {({ fields }) => ( <div> {fields.map((name, index) => ( <div key={name} style={{ marginBottom: "1rem" }}> <Field name={`contacts[${index}].name`}> {({ input, meta }) => ( <div> <label>姓名</label> <input {...input} placeholder="请输入姓名" /> {/* 显示姓名字段错误 */} {meta.error && meta.touched && ( <span style={{ color: "red", fontSize: "0.8rem" }}> {meta.error} </span> )} </div> )} </Field> <Field name={`contacts[${index}].email`}> {({ input, meta }) => ( <div> <label>邮箱</label> <input {...input} placeholder="请输入邮箱" /> {/* 显示邮箱字段错误 */} {meta.error && meta.touched && ( <span style={{ color: "red", fontSize: "0.8rem" }}> {meta.error} </span> )} </div> )} </Field> <button type="button" onClick={() => fields.remove(index)} style={{ marginTop: "0.5rem" }} > 删除联系人 </button> </div> ))} <button type="button" onClick={() => fields.push({ name: "", email: "" })} > 添加联系人 </button> </div> )} </FieldArray>
3. 将验证函数传入Form组件
最后把我们写好的validate函数传给Form组件的validate属性,这样表单提交或者字段值变化时就会自动触发验证:
<Form onSubmit={onSubmit} validate={validate} initialValues={{ contacts: [{ name: "", email: "" }] }} > {({ handleSubmit, values }) => ( <form onSubmit={handleSubmit}> {/* 上面的FieldArray代码 */} <button type="submit">提交</button> <pre>{JSON.stringify(values, 0, 2)}</pre> </form> )} </Form>
完整可运行代码示例
import React from "react"; import { Form, Field, FieldArray } from "react-final-form"; const onSubmit = (values) => { alert(JSON.stringify(values, 0, 2)); }; const validate = (values) => { const errors = {}; if (values.contacts) { errors.contacts = []; values.contacts.forEach((contact, index) => { const contactErrors = {}; if (!contact.name?.trim()) { contactErrors.name = "姓名不能为空"; } if (contact.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(contact.email)) { contactErrors.email = "请输入有效的邮箱地址"; } if (Object.keys(contactErrors).length > 0) { errors.contacts[index] = contactErrors; } }); } return errors; }; const App = () => ( <div style={{ maxWidth: 600, margin: "0 auto", padding: "2rem" }}> <h1>联系人表单(带数组字段验证)</h1> <Form onSubmit={onSubmit} validate={validate} initialValues={{ contacts: [{ name: "", email: "" }] }} > {({ handleSubmit, values }) => ( <form onSubmit={handleSubmit}> <FieldArray name="contacts"> {({ fields }) => ( <div> {fields.map((name, index) => ( <div key={name} style={{ marginBottom: "1.5rem" }}> <h3>联系人 #{index + 1}</h3> <Field name={`contacts[${index}].name`}> {({ input, meta }) => ( <div style={{ marginBottom: "0.5rem" }}> <label style={{ display: "block", marginBottom: "0.2rem" }}>姓名</label> <input {...input} placeholder="请输入姓名" style={{ padding: "0.5rem", width: "100%" }} /> {meta.error && meta.touched && ( <span style={{ color: "red", fontSize: "0.8rem" }}> {meta.error} </span> )} </div> )} </Field> <Field name={`contacts[${index}].email`}> {({ input, meta }) => ( <div style={{ marginBottom: "0.5rem" }}> <label style={{ display: "block", marginBottom: "0.2rem" }}>邮箱</label> <input {...input} placeholder="请输入邮箱" style={{ padding: "0.5rem", width: "100%" }} /> {meta.error && meta.touched && ( <span style={{ color: "red", fontSize: "0.8rem" }}> {meta.error} </span> )} </div> )} </Field> <button type="button" onClick={() => fields.remove(index)} style={{ padding: "0.3rem 0.8rem", backgroundColor: "#ff4444", color: "white", border: "none", borderRadius: "4px" }} > 删除联系人 </button> </div> ))} <button type="button" onClick={() => fields.push({ name: "", email: "" })} style={{ padding: "0.5rem 1rem", backgroundColor: "#00C851", color: "white", border: "none", borderRadius: "4px" }} > 添加联系人 </button> </div> )} </FieldArray> <div style={{ marginTop: "2rem" }}> <button type="submit" style={{ padding: "0.5rem 1.5rem", backgroundColor: "#33b5e5", color: "white", border: "none", borderRadius: "4px" }} > 提交表单 </button> </div> <div style={{ marginTop: "2rem" }}> <h3>当前表单值:</h3> <pre>{JSON.stringify(values, 0, 2)}</pre> </div> </form> )} </Form> </div> ); export default App;
这样修改后,每个数组项的姓名和邮箱字段都会有对应的验证规则,错误提示会在用户触碰字段且不符合规则时显示,提交表单时也会触发全局验证,确保所有字段都符合要求。
内容的提问来源于stack exchange,提问作者leuction
相关产品推荐
相关产品推荐

