Skip to content

Instantly share code, notes, and snippets.

@ilhamgusti
Created January 7, 2022 15:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ilhamgusti/ed0fd354a16497720f868039c7e57e40 to your computer and use it in GitHub Desktop.
Save ilhamgusti/ed0fd354a16497720f868039c7e57e40 to your computer and use it in GitHub Desktop.
hooks for handle form input
import { useState } from "react";
function getInputOnChange(setValue) {
return (val) => {
if (!val) {
setValue(val);
} else if (typeof val === "function") {
setValue(val);
} else if (typeof val === "object" && "nativeEvent" in val) {
const { currentTarget } = val;
if (currentTarget.type === "checkbox") {
setValue(currentTarget.checked);
} else {
setValue(currentTarget.value);
}
} else {
setValue(val);
}
};
}
export function useForm({
initialValues,
validationRules = {},
errorMessages = {}
}) {
const initialErrors = Object.keys(initialValues).reduce((acc, field) => {
acc[field] = null;
return acc;
}, {});
const [errors, setErrors] = useState(initialErrors);
const [values, setValues] = useState(initialValues);
const resetErrors = () => setErrors(initialErrors);
const reset = () => {
setValues(initialValues);
resetErrors();
};
const validate = () => {
let isValid = true;
const validationErrors = Object.keys(values).reduce((acc, field) => {
if (
validationRules &&
typeof validationRules[field] === "function" &&
!validationRules[field](values[field], values)
) {
acc[field] = errorMessages[field] || true;
isValid = false;
} else {
acc[field] = null;
}
return acc;
}, {});
setErrors(validationErrors);
return isValid;
};
const validateField = (field) =>
setErrors((currentErrors) => ({
...currentErrors,
[field]:
typeof validationRules[field] === "function"
? validationRules[field](values[field], values)
? null
: errorMessages[field] || true
: null
}));
const setFieldError = (field, error) =>
setErrors((currentErrors) => ({ ...currentErrors, [field]: error }));
const setFieldValue = (field, value) => {
setValues((currentValues) => ({ ...currentValues, [field]: value }));
setFieldError(field, null);
};
const onSubmit = (handleSubmit) => (event) => {
event && event.preventDefault();
validate() && handleSubmit(values);
};
const getInputProps = (field, options) => ({
[options?.type === "checkbox" ? "checked" : "value"]: values[field],
onChange: getInputOnChange((val) => setFieldValue(field, val)),
error: errors[field] || undefined
});
return {
values,
errors,
validate,
reset,
setErrors,
setValues,
setFieldValue,
setFieldError,
validateField,
resetErrors,
onSubmit,
getInputProps
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment