Formik + Yup

useFormik vs Form của formik

import React from 'react';
2 import { Formik } from 'formik';
3 import * as Yup from 'yup';
4
5 const SignupForm = () => {
6 return (
7 <Formik
8 initialValues={{ firstName: '', lastName: '', email: '' }}
9 validationSchema={Yup.object({
10 firstName: Yup.string()
11 .max(15, 'Must be 15 characters or less')
12 .required('Required'),
13 lastName: Yup.string()
14 .max(20, 'Must be 20 characters or less')
15 .required('Required'),
16 email: Yup.string().email('Invalid email address').required('Required'),
17 })}
18 onSubmit={(values, { setSubmitting }) => {
19 setTimeout(() => {
20 alert(JSON.stringify(values, null, 2));
21 setSubmitting(false);
22 }, 400);
23 }}
24 >
25 {formik => (
26 <form onSubmit={formik.handleSubmit}>
27 <label htmlFor="firstName">First Name</label>
28 <input
29 id="firstName"
30 type="text"
31 {...formik.getFieldProps('firstName')}
32 />
33 {formik.touched.firstName && formik.errors.firstName ? (
34 <div>{formik.errors.firstName}</div>
35 ) : null}
36
37 <label htmlFor="lastName">Last Name</label>
38 <input
39 id="lastName"
40 type="text"
41 {...formik.getFieldProps('lastName')}
42 />
43 {formik.touched.lastName && formik.errors.lastName ? (
44 <div>{formik.errors.lastName}</div>
45 ) : null}
46
47 <label htmlFor="email">Email Address</label>
48 <input id="email" type="email" {...formik.getFieldProps('email')} />
49 {formik.touched.email && formik.errors.email ? (
50 <div>{formik.errors.email}</div>
51 ) : null}
52
53 <button type="submit">Submit</button>
54 </form>
55 )}
56 </Formik>
57 );
58 };
(Form của formik là một component, đươc convert từ useFormik to JSX )
Khi dùng component Form của formik ta có thể sử dụng các component ví dụ như label, <Field>, <ErrorMessage> code sẽ gọn hơn và dễ dùng. Cùng chức năng với component <Field> chính là useFeild nhưng via React Hooks
import React from 'react';
2 import ReactDOM from 'react-dom';
3 import { Formik, Form, useField } from 'formik';
4 import * as Yup from 'yup';
5
6 const MyTextInput = ({ label, ...props }) => {
7 // useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
8 // which we can spread on <input>. We can use field meta to show an error
9 // message if the field is invalid and it has been touched (i.e. visited)
10 const [field, meta] = useField(props);
11 return (
12 <>
13 <label htmlFor={props.id || props.name}>{label}</label>
14 <input className="text-input" {...field} {...props} />
15 {meta.touched && meta.error ? (
16 <div className="error">{meta.error}</div>
17 ) : null}
18 </>
19 );
20 };
21
22 const MyCheckbox = ({ children, ...props }) => {
23 // React treats radios and checkbox inputs differently other input types, select, and textarea.
24 // Formik does this too! When you specify `type` to useField(), it will
25 // return the correct bag of props for you -- a `checked` prop will be included
26 // in `field` alongside `name`, `value`, `onChange`, and `onBlur`
27 const [field, meta] = useField({ ...props, type: 'checkbox' });
28 return (
29 <div>
30 <label className="checkbox-input">
31 <input type="checkbox" {...field} {...props} />
32 {children}
33 </label>
34 {meta.touched && meta.error ? (
35 <div className="error">{meta.error}</div>
36 ) : null}
37 </div>
38 );
39 };
40
41 const MySelect = ({ label, ...props }) => {
42 const [field, meta] = useField(props);
43 return (
44 <div>
45 <label htmlFor={props.id || props.name}>{label}</label>
46 <select {...field} {...props} />
47 {meta.touched && meta.error ? (
48 <div className="error">{meta.error}</div>
49 ) : null}
50 </div>
51 );
52 };
53
54 // And now we can use these
55 const SignupForm = () => {
56 return (
57 <>
58 <h1>Subscribe!</h1>
59 <Formik
60 initialValues={{
61 firstName: '',
62 lastName: '',
63 email: '',
64 acceptedTerms: false, // added for our checkbox
65 jobType: '', // added for our select
66 }}
67 validationSchema={Yup.object({
68 firstName: Yup.string()
69 .max(15, 'Must be 15 characters or less')
70 .required('Required'),
71 lastName: Yup.string()
72 .max(20, 'Must be 20 characters or less')
73 .required('Required'),
74 email: Yup.string()
75 .email('Invalid email address')
76 .required('Required'),
77 acceptedTerms: Yup.boolean()
78 .required('Required')
79 .oneOf([true], 'You must accept the terms and conditions.'),
80 jobType: Yup.string()
81 .oneOf(
82 ['designer', 'development', 'product', 'other'],
83 'Invalid Job Type'
84 )
85 .required('Required'),
86 })}
87 onSubmit={(values, { setSubmitting }) => {
88 setTimeout(() => {
89 alert(JSON.stringify(values, null, 2));
90 setSubmitting(false);
91 }, 400);
92 }}
93 >
94 <Form>
95 <MyTextInput
96 label="First Name"
97 name="firstName"
98 type="text"
99 placeholder="Jane"
100 />
101
102 <MyTextInput
103 label="Last Name"
104 name="lastName"
105 type="text"
106 placeholder="Doe"
107 />
108
109 <MyTextInput
110 label="Email Address"
111 name="email"
112 type="email"
113 placeholder="jane@formik.com"
114 />
115
116 <MySelect label="Job Type" name="jobType">
117 <option value="">Select a job type</option>
118 <option value="designer">Designer</option>
119 <option value="development">Developer</option>
120 <option value="product">Product Manager</option>
121 <option value="other">Other</option>
122 </MySelect>
123
124 <MyCheckbox name="acceptedTerms">
125 I accept the terms and conditions
126 </MyCheckbox>
127
128 <button type="submit">Submit</button>
129 </Form>
130 </Formik>
131 </>
132 );
133 };

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.