表單
在mall項目中我們不在使用ant提供的form去創(chuàng)建表單掌实,取而代之的是使用formik 以及 yup配合使用來做表單的驗證。下面我會主要介紹一下formik和yup中的一些概念蛾扇,以及會創(chuàng)建一個playground大家可以去上面根據(jù)文檔自行探索更加高級的玩法。
formik
formik是一個小型的lib,是為我們解決系統(tǒng)中使用表單所帶來的痛苦栅炒,它可以幫我們解決三個最煩人的部分
- 獲取表單狀態(tài)的值和表單狀態(tài)
- 驗證和錯誤消息
- 處理表單提交
formit的設(shè)計比redux-form更加優(yōu)雅鱼喉,我們知道表單就是為了收集一些數(shù)據(jù)剩辟,然后進行提交蝗罗。所以這種狀態(tài)不需要我們存放到reducer中去,可以內(nèi)部的將這些表單項產(chǎn)生的數(shù)據(jù)消化掉。
formik Api預覽
formik為我們提供了一下Api
<Formik />是一個可以幫助你構(gòu)建表單的組件纤虽,我們有三種方式可以渲染<Formik />
- <Formik component> //優(yōu)先考慮使用
- <Formik render> //不要和上面的混合使用
- <Formik children> //優(yōu)先使用上兩者
這里有個練習的地方Formik Playground
我們可以把Formik看成一個組件,內(nèi)部的子組件時通過component, render, children的方式注入的杰刽。子組件的產(chǎn)生的onChange事件回調(diào)給父組件悠抹,父組件進行處理后將產(chǎn)生的數(shù)據(jù)以及錯誤信息回調(diào)給子組件锌钮。這樣兩者之間就能進行通信了。
┌─────────────────────────┬───Formik──▲────────────────────────┐
│ │ │ │
│ inject data and action│ │ │
│ │ │callback │
│ validate│ │ │
│ │ │ │
│ ┌───────────▼Component──┴─────────┐ │
│ │ │ │
│ │ ┌───────────────────────┐ │ │
│ │ │ render componet │ │ │
│ │ │ show error │ │ │
│ │ │ show values │ │ │
│ │ └───────────────────────┘ │ │
│ └─────────────────────────────────┘ │
│ │
│ │
└──────────────────────────────────────────────────────────────┘
如何驗證表單
Formik有兩個屬性一個是validate
函數(shù)簽名是(values: Values) => FormikErrors<Values> | Promise<any>
我們可以通過這個屬性進行手動的驗證,是一種無依賴,直接的方式來驗證您的表單。
const validate = values => {
let errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
//...
return errors;
};
另外一個是validationSchema
這是配合yup進行驗證赴涵。函數(shù)簽名是
validationSchema?: Schema | (() => Schema)
const formSchema = yup.object().shape({
email: yup.string().required("不能為空")
});
如何提交表單
Formik有個屬性一個是onSubmit
函數(shù)簽名是onSubmit: (values: Values, formikBag: FormikBag) => void
其中values就是我們表單收集的數(shù)據(jù)
const handleOnSubmit = (values: FormValueType, formikBag: FormikBag) => {
// 這里可以通過actions里的函數(shù)去給表單里的filed設(shè)置或者設(shè)置錯誤
// actions.setFieldValue("email", "15737937865@163.com");
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
formikBag.setSubmitting(false);
}, 1000);
};