Last active
April 15, 2019 07:12
-
-
Save ejoo/96d7f6356e2a2700ef2ee62ae17f6168 to your computer and use it in GitHub Desktop.
React Form Custom Hook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function useForm(initial, schema) { | |
const [values, setState] = React.useState(initial); | |
const [touched, setTouched] = React.useState([]); | |
const [errors, setErrors] = React.useState(null); | |
// update field value on change on any input in the form | |
const onFormChange = e => { | |
const { name, value } = e.target; | |
setState({ ...values, [name]: value }); | |
}; | |
// update whether item is touched or not. | |
const onFormBlur = e => { | |
const { name } = e.target; | |
if (!touched.includes(name)) { | |
setTouched([...touched, name]); | |
} | |
}; | |
const error = key => { | |
if (touched.includes(key) && errors[key]) { | |
return errors[key]; | |
} | |
return null; | |
}; | |
// apply joy validations | |
React.useEffect(() => { | |
schema | |
.validate(values, { abortEarly: false }) | |
.then(res => { | |
setErrors({}); | |
}) | |
.catch(error => { | |
const newErrors = {}; | |
error.inner.forEach(err => { | |
if (touched.includes(err.path)) { | |
newErrors[err.path] = err.message; | |
} | |
return null; | |
}); | |
setErrors(newErrors); | |
}); | |
}, [values, touched]); | |
return { values, setState, touched, onFormChange, onFormBlur, errors, error }; | |
} | |
// Usage | |
namespace UsageSFC { | |
export interface IProps { | |
onSubmit(data:ICompanyDetails): void; | |
} | |
} | |
export const BusinessSettings: React.SFC<UsageSFC.IProps> = props => { | |
const initialValues:ICompany = { | |
company: "", | |
tagline: "the company name", | |
website: "", | |
address: "", | |
businessHours: "" | |
}; | |
const validation = yup.object().shape({ | |
company: yup.string().required("Company name is required bro."), | |
tagline: yup.string().required() | |
}); | |
const { values, onFormChange, onFormBlur, errors, error } = useForm( | |
initialValues, | |
validation | |
); | |
return ( | |
<div className='update-business'> | |
<form onChange={onFormChange} onBlur={onFormBlur}> | |
<input type='text' name='company' /> | |
<p>{error('company')}</p> | |
... | |
</form> | |
</div> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment