Skip to content

Instantly share code, notes, and snippets.

@ejoo
Last active April 15, 2019 07:12
Show Gist options
  • Save ejoo/96d7f6356e2a2700ef2ee62ae17f6168 to your computer and use it in GitHub Desktop.
Save ejoo/96d7f6356e2a2700ef2ee62ae17f6168 to your computer and use it in GitHub Desktop.
React Form Custom Hook
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