Created
January 7, 2022 15:43
-
-
Save ilhamgusti/ed0fd354a16497720f868039c7e57e40 to your computer and use it in GitHub Desktop.
hooks for handle form input
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
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