我第一次尝试使用 formik 和 yup valiation, 我创建了一个选择字段并放置了一些选项, 每次选择该选项后,它都会显示验证错误消息,
谁能帮我解决这个问题
错误的codesandbox链接
const InvestmentDetail = ({ data, changeValue }) => {
return (
<div className="text-2xl flex flex-col w-full justify-between container w-[1128px] gap-[42px] pt-[35px] pb-[50px] ">
{investmentDetails.map((i, _i) => {
return (
<>
<div>
<div className="text-[22px]"> {i.label} </div>
<div className="text-lg text-[#404040]"> {i.desc}</div>
</div>
<div className="flex flex-col w-full">
<Field
as="select"
name={i.label}
id="dropdown"
className="appearance-none relative !w-full p-[16px] h-[4.06rem] border-[#787878] rounded-[6px] border-solid border-[1px] bg-[#fff]"
value={data[i.label]}
onChange={(e) => changeValue(i.label, e.target.value)}
>
<option value="" className="text-2xl">
Select
</option>
{i.options.map((i) => (
<>
<option key={i} value={i} className="text-2xl">
{i}
</option>
<br />
</>
))}
</Field>
<ErrorMessage
name={i.label}
component="div"
className="error bottom-[-10px] text-[red] text-xl"
/>
</div>
</>
);
})}
</div>
);
};
export default function App() {
const [formData, setFormData] = useState(initialStates);
useEffect(() => {}, [formData, setFormData]);
const changeValue = (key, value) => {
setFormData((prevData) => ({
...prevData,
[key]: value
}));
};
return (
<>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={() => console.log("high")}
>
<Form>
<InvestmentDetail data={formData} changeValue={changeValue} />
</Form>
</Formik>{" "}
</>
);
}
验证模式和初始状态:
import * as Yup from "yup";
export const investmentDetails = [
{
label: "Account Type",
desc: "",
options: ["Saving", "Current"]
},
{
label: "Portfolio/Strategy Name",
desc: "",
options: ["Saving", "Current"]
},
{
label: "Fund Fees Category",
desc: "Fees preview according to selection",
options: ["Saving", "Current"]
},
{
label: "Investment Category",
desc: "Preview only when systematic transfer plan is selected",
options: ["Saving", "Current"]
},
{
label: "Country of Tax Residency",
desc: "Preview only when systematic transfer plan is selected",
options: ["Saving", "Current"]
},
{
label: "No. of Account Holders",
desc: "Preview only when systematic transfer plan is selected",
options: ["Saving", "Current"]
},
{
label: "Investment Mode",
desc: "Preview only when systematic transfer plan is selected",
options: ["Saving", "Current"]
}
];
export const initialValues = {
"Account Type": "",
"Portfolio/Strategy Name": "",
"Fund Fees Category": "",
"Investment Category": "",
"Communication Address": "",
"Country of Tax Residency": "",
"No. of Account Holders": "",
"Quantum of Investment": "",
"Investment Mode": ""
};
export const initialStates = {
"Account Type": "",
"Portfolio/Strategy Name": "",
"Fund Fees Category": "",
"Investment Category": "",
"Communication Address": "",
"Country of Tax Residency": "",
"No. of Account Holders": 1,
"Quantum of Investment": "",
"Investment Mode": ""
};
export const validationSchema = Yup.object().shape({
"Account Type": Yup.string().required("Required"),
"Portfolio/Strategy Name": Yup.string().required("Required"),
"Fund Fees Category": Yup.string().required("Required"),
"Investment Category": Yup.string().required("Required"),
"Country of Tax Residency": Yup.string().required("Required"),
"No. of Account Holders": Yup.number()
.required("Required")
.min(1, "Should be at least 1"),
"Investment Mode": Yup.string().required("Required")
});
您应该使用
formik
功能来访问或更改应用程序中的值,并防止在 onChange
组件的 Field
属性上设置字段值,因为 <Field/>
自动设置文档中提到的值。
将自动将输入连接到 Formik。它使用 name 属性来匹配 Formik 状态。将默认为 HTML 元素。<Field />
<Field
as="select"
name={i.label}
id="dropdown"
className="appearance-none relative !w-full p-[16px] h-[4.06rem] border-[#787878] rounded-[6px] border-solid border-[1px] bg-[#fff]"
value={data[i.label]}
>
<option value="" className="text-2xl">
Select
</option>
{i.options.map((i) => (
<>
<option key={i} value={i} className="text-2xl">
{i}
</option>
<br />
</>
))}
</Field>
实际上
formData
App 组件中的 setState 是多余的,您将在 onSubmit 回调上访问值,如下所示:
<Formik
validateOnChange={true}
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
>
<Form>
<InvestmentDetail data={formData} changeValue={changeValue} />
</Form>
</Formik>