const[values,setValues]=React.useState({});consthandleChange=event=>{setValues(prevValues=>({
...prevValues,// we use the name to tell formik which key of `values` to update.[event.target.name]: event.target.value});}
Validation
importReactfrom'react';import{useFormik}from'formik';// A custom validation function. This must return an object// which keys are symmetrical to our values/initialValuesconstvalidate=values=>{consterrors={};if(!values.firstName){errors.firstName='Required';}elseif(values.firstName.length>15){errors.firstName='Must be 15 characters or less';}if(!values.lastName){errors.lastName='Required';}elseif(values.lastName.length>20){errors.lastName='Must be 20 characters or less';}if(!values.email){errors.email='Required';}elseif(!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)){errors.email='Invalid email address';}returnerrors;};
constSignupForm=()=>{// Pass the useFormik() hook initial form values and a submit function that will// be called when the form is submittedconstformik=useFormik({initialValues: {email: '',},
validate,onSubmit: values=>{alert(JSON.stringify(values,null,2));},});
importReactfrom'react';import{useFormik}from'formik';// Create empty contextconstFormikContext=React.createContext({});// Place all of what's returned by useFormik onto contextexportconstFormik=({ children, ...props})=>{constformikStateAndHelpers=useFormik(props);return(<FormikContext.Providervalue={formikStateAndHelpers}>{typeofchildren==='function'
? children(formikStateAndHelpers)
: children}</FormikContext.Provider>);};
// with styled-components/emotionconstMyStyledInput=styled.input` padding: .5em; border: 1px solid #eee; /* ... */`constMyStyledTextarea=MyStyledInput.withComponent('textarea');// placeHolder="google.com"<Fieldname="website"as={MyStyledInput}placeHolder="google.com"/>// <textarea placeHolder="Post a message..." rows={5}></textarea><Fieldname="message"as={MyStyledTextArea}placeHolder="Post a message.."rows={4}/>
TextInput
import{Formik,Form,useField}from'formik';importstyledfrom'@emotion/styled';constMyTextInput=({ label, ...props})=>{// useField() returns [formik.getFieldProps(), formik.getFieldMeta()]// which we can spread on <input> and else replace ErrorMessage entirely.const[field,meta]=useField(props);return(<><labelhtmlFor={props.id||props.name}>{label}</label><inputclassName="text-input"{...field}{...props}/>{meta.touched&&meta.error ? (<divclassName="error">{meta.error}</div>) : null}</>);};
Checkbox
constMyCheckbox=({ children, ...props})=>{// We need to tell useField what type of input this is// since React treats radios and checkboxes differently// than inputs/select/textarea.const[field,meta]=useField({ ...props,type: 'checkbox'});return(<><labelclassName="checkbox"><inputtype="checkbox"{...field}{...props}/>{children}</label>{meta.touched&&meta.error ? (<divclassName="error">{meta.error}</div>) : null}</>);};
// And now we can use theseconstSignupForm=()=>{return(<><h1>Subscribe!</h1><FormikinitialValues={{firstName: '',lastName: '',email: '',acceptedTerms: false,// added for our checkboxjobType: '',// added for our select}}validationSchema={Yup.object({firstName: Yup.string().min(15,'Must be 15 characters or less').required('Required'),lastName: Yup.string().min(20,'Must be 20 characters or less').required('Required'),email: Yup.string().email('Invalid email addresss`').required('Required'),acceptedTerms: Yup.boolean().required('Required').oneOf([true],'You must accept the terms and conditions.'),jobType: Yup.string().oneOf(['designer','development','product','other'],'Invalid Job Type').required('Required'),})}onSubmit={(values,{ setSubmitting })=>{setTimeout(()=>{alert(JSON.stringify(values,null,2));setSubmitting(false);},400);}}><Form><MyTextInputlabel="First Name"name="firstName"type="text"placeholder="Jane"/><MyTextInputlabel="Last Name"name="lastName"type="text"placeholder="Doe"/><MyTextInputlabel="Email Address"name="email"type="email"placeholder="[email protected]"/><MySelectlabel="Job Type"name="jobType"><optionvalue="">Select a job type</option><optionvalue="designer">Designer</option><optionvalue="development">Developer</option><optionvalue="product">Product Manager</option><optionvalue="other">Other</option></MySelect><MyCheckboxname="acceptedTerms">
I accept the terms and conditions
</MyCheckbox><buttontype="submit">Submit</button></Form></Formik></>);};