useForm.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { useState } from "react";
  2. export const useForm = initialValues => {
  3. const [form, setFormProp] = useState(initialValues);
  4. const validator = (rules, value, allForm) => {
  5. const valid = Object.keys(rules).reduce((prev, elem) => {
  6. if (prev) return true
  7. const check = rules[elem].cb(value, allForm[rules[elem].match])
  8. if (!prev && check) return check
  9. return false
  10. }, false)
  11. return valid;
  12. };
  13. const onChangeHandler = e => {
  14. const { name, value } = e.target;
  15. setFormProp(prevState => {
  16. const values = Object.keys(prevState.form).reduce((prev, elem) => {
  17. if (elem === name) return prev.concat(value);
  18. return prev.concat(prevState.form[elem].value);
  19. }, []);
  20. return {
  21. ...prevState,
  22. form: {
  23. ...prevState.form,
  24. [name]: {
  25. ...prevState.form[name],
  26. value
  27. }
  28. },
  29. validForm: values.some(value => value)
  30. };
  31. });
  32. };
  33. const focusEvent = e => {
  34. const { name } = e.target;
  35. setFormProp(prevState => ({
  36. ...prevState,
  37. form: {
  38. ...prevState.form,
  39. [name]: {
  40. ...prevState.form[name],
  41. touch: true
  42. }
  43. }
  44. }));
  45. };
  46. const blurEvent = e => {
  47. const { name, value } = e.target;
  48. const prevValues = Object.keys(form.form).reduce((prev, elem) => {
  49. return { ...prev, [elem]: elem === name ? value : form.form[elem].value };
  50. }, {});
  51. setFormProp(prevState => {
  52. const valid = validator(prevState.form[name].validation, value, prevValues);
  53. return {
  54. ...prevState,
  55. form: {
  56. ...prevState.form,
  57. [name]: {
  58. ...prevState.form[name],
  59. fail: value ? valid : true
  60. }
  61. }
  62. };
  63. });
  64. };
  65. const returnAllValues = () => {
  66. return Object.keys(form.form).reduce((prev, elem) => {
  67. return { ...prev, [elem]: form.form[elem].value };
  68. }, {});
  69. };
  70. return [form, { onChangeHandler, returnAllValues, focusEvent, blurEvent }];
  71. };