{"id":20760297,"url":"https://github.com/onukwilip/use-manage-form","last_synced_at":"2025-07-20T20:05:39.825Z","repository":{"id":65407782,"uuid":"590958690","full_name":"onukwilip/use-manage-form","owner":"onukwilip","description":"A react hook used to manage form and form input states","archived":false,"fork":false,"pushed_at":"2023-03-22T15:21:50.000Z","size":750,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-10T07:06:07.491Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onukwilip.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-19T16:00:38.000Z","updated_at":"2023-03-27T19:43:53.000Z","dependencies_parsed_at":"2025-01-18T05:25:33.501Z","dependency_job_id":"9b0b0451-515d-413c-8fac-921b2a487dcf","html_url":"https://github.com/onukwilip/use-manage-form","commit_stats":{"total_commits":6,"total_committers":1,"mean_commits":6.0,"dds":0.0,"last_synced_commit":"a58e2d04d3d2e2449aa1f1169f59006d386c8cc3"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/onukwilip/use-manage-form","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onukwilip%2Fuse-manage-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onukwilip%2Fuse-manage-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onukwilip%2Fuse-manage-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onukwilip%2Fuse-manage-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onukwilip","download_url":"https://codeload.github.com/onukwilip/use-manage-form/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onukwilip%2Fuse-manage-form/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266189677,"owners_count":23890065,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T10:13:03.450Z","updated_at":"2025-07-20T20:05:39.800Z","avatar_url":"https://github.com/onukwilip.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# USE-MANAGE-FORM\n\nThe use-manage-form is a React hook used to manage form states in a component. As a React developer, many a time i've come across scenarios where i'll have to manage multiple states and validation logic because of a single form, that's what inspired me to develop this hook and publish it so I and developers like me can use them to make development easier.\n\n## Installation\n\nInorder to install this package, one should run `npm install use-manage-form` **OR** `yarn add use-manage-form`. To install a specific version run `npm install use-manage-form@version` **OR** `yarn add use-manage-form@version`. Replace _version_ with the package version **e.g 1.0.0**.\n\n## How to use the package\n\nTo use the package/hook, you import it at the top of your `.js`/`.ts` file.\n\n```javascript\nimport { useInput, useForm } from \"use-manage-form\";\n```\n\n### useInput hook\n\nThe `useInput` hook is responsible for managing each input state, properties and validation. E.g:\n\n```javascript\nconst { value, isValid, inputIsInValid, onChange, onBlur, reset } =\n  useInput(validateFunction);\n```\n\nIt returns an object containing the\n\n- `value` of the input\n- `isValid` _boolean_ if the input is valid or not (based on the validateFunction)\n- `inputIsInValid` _boolean_ if the input field is inValid or not (based on the validateFunction and if the input field has been touched)\n- `onChange` function to be executed inorder to change the value of the input\n- `onBlur` function to be executed to indicate that the input has been touched (to set the inputIsInvalid value properly)\n- `reset` function to be executed to reset the value of the input and inputWasTouched to empty and false respectively\n\nThe `useInput` hook also accepts a function `validateFunction` as a parameter that should return the input validator. It passes the input value as a parameter to the function `validateFunction`. E.g:\n\n```javascript\nuseInput((/**@type String*/ value) =\u003e {\n  return value.trim() !== \"\";\n});\n```\n\nInorder to update the input value you should pass the `onChange` function from `useInput` hook to the input's `onChange` prop. I.e:\n\n```javascript\n\u003cinput\n  type=\"text\"\n  onChange={(/**@type Event */ e) =\u003e {\n    onChange(e.target?.value);\n  }}\n  id=\"name\"\n/\u003e\n```\n\nTo perform two way binding, you also need to pass the `value` property from the `useInput` hook to the input's `value` prop. I.e:\n\n```javascript\n\u003cinput\n  type=\"text\"\n  onChange={(/**@type Event */ e) =\u003e {\n    onChange(e.target?.value);\n  }}\n  id=\"name\"\n  value={value}\n/\u003e\n```\n\nTo indicate that the input was touched you'll need to pass the `onBlur` function from the `useInput` hook to the input's `onBlur` prop. I.e:\n\n```javascript\n\u003cinput\n  type=\"text\"\n  onChange={(/**@type Event */ e) =\u003e {\n    onChange(e.target?.value);\n  }}\n  onBlur={() =\u003e {\n    onBlur();\n  }}\n  id=\"name\"\n  value={value}\n/\u003e\n```\n\nTo reset an input, just call the `reset` function. E.g:\n\n```javascript\nreset();\n```\n\nYou can use the `inputIsInValid` property to show some error if the input field is invalid. The difference between the `isValid` and `inputIsInValid` properties are\n\n- `isValid` returns `true` or `false` based on the `validateFunction` passed into the `useInput` hook.\n- `inputIsInValid` returns `true` or `false` based on both the `isValid` and `inputWasTouched` properties.\n- `inputIsInValid` is used for error stylings. I.e: The input is always invalid because it's empty at first, therefore, the `isValid` prop returns `false`. If you use the `isValid` prop to determine the error styling (Display input error message), it will be displayed when the page is loaded, But if the `inputIsInValid` prop is used - the error would only be displayed if the user has touched the input or has clicked the submit button. E.g:\n\n```javascript\n\u003cdiv\u003e\n  \u003cinput\n    type=\"text\"\n    onChange={(/**@type Event */ e) =\u003e {\n      onChange(e.target?.value);\n    }}\n    onBlur={() =\u003e {\n      onBlur();\n    }}\n    value={value}\n    id=\"name\"\n  /\u003e\n  {inputIsInValid \u0026\u0026 \u003cp className=\"error-text\"\u003eName must not be empty.\u003c/p\u003e}\n\u003c/div\u003e\n```\n\nYou can rename each property in case you are using multiple `useInput` . E.g:\n\n```javascript\nconst {\n  value: firstName,\n  isValid: firstNameIsValid,\n  inputIsInValid: firstNameInputIsInValid,\n  onChange: firstNameChangeHandler,\n  onBlur: firstNameBlurHandler,\n  reset: resetFirstName,\n} = useInput((value) =\u003e value.trim() !== \"\");\n```\n\n### useForm hook\n\nThe `useForm` hook is used to manage the states of a whole form, it manages the **formIsValid** state and other functions.\n\nThe `useForm` hook returns three properties namely:\n\n```javascript\n{\n    executeBlurHandlers,\n    formIsValid,\n    reset,\n}\n```\n\n- The `executeBlurHandlers` executes all form input `onBlur` functions passed to the `useForm` hook.\n- The `formIsValid` returns `true`/`false`, based on the function passed to the useForm `hook`.\n- The `reset` resets all form inputs passed to the `useForm` hook.\n\nThe `useForm` hook accepts an object containing:\n\n- **`blurHandlers`**: The list of all input `onBlur` functions to be executed (to be executed when form is submitted, but **NOT** validated, it sets the `inputWasTouched` value of all inputs passed into it to `true` and `inputIsInValid` states to true for invalid inputs).\n- **`validateOptions`**: The `validateFunction` used to determine if the form is valid or not\n- **`resetHandlers`**: The list of all input `reset` functions (To reset all input values and `inputWasTouched` values to empty and false respectively)\n\nTherefore, the `useForm` is to be called this way:\n\n```javascript\nconst { executeBlurHandlers, formIsValid, reset } = useForm({\n  blurHandlers: [firstNameBlurHandler, lastNameBlurHandler, emailBlurHandler],\n  validateOptions: () =\u003e firstNameIsValid \u0026\u0026 lastNameIsValid \u0026\u0026 emailIsValid,\n  resetHandlers: [resetFirstName, resetLastName, resetEmail],\n});\n```\n\nThe `onSubmit` function passed to the form could be then implemented this way:\n\n```javascript\nconst onSubmit = (/**@type Event*/ e) =\u003e {\n  e.preventDefault();\n\n  if (!formIsValid) {\n    executeBlurHandlers();\n    return false;\n  }\n};\n...\nreturn(\n        \u003cform onSubmit={onSubmit}\u003e\n        \u003c/form\u003e\n    )\n```\n\nAt the end our code base should be similar to this\n\n```javascript\nimport { useForm, useInput } from \"use-manage-form\";\n\nconst BasicForm = (props) =\u003e {\n  const {\n    value: firstName,\n    isValid: firstNameIsValid,\n    inputIsInValid: firstNameInputIsInValid,\n    onChange: firstNameChangeHandler,\n    onBlur: firstNameBlurHandler,\n    reset: resetFirstName,\n  } = useInput((value) =\u003e value.trim() !== \"\");\n\n  const {\n    value: lastName,\n    isValid: lastNameIsValid,\n    inputIsInValid: lastNameInputIsInValid,\n    onChange: lastNameChangeHandler,\n    onBlur: lastNameBlurHandler,\n    reset: resetLastName,\n  } = useInput((value) =\u003e value.trim() !== \"\");\n\n  const {\n    value: email,\n    isValid: emailIsValid,\n    inputIsInValid: emailInputIsInValid,\n    onChange: emailChangeHandler,\n    onBlur: emailBlurHandler,\n    reset: resetEmail,\n  } = useInput((value) =\u003e value.trim() !== \"\" \u0026\u0026 value?.includes(\"@\"));\n\n  const { executeBlurHandlers, formIsValid, reset } = useForm({\n    blurHandlers: [firstNameBlurHandler, lastNameBlurHandler, emailBlurHandler],\n    validateOptions: () =\u003e firstNameIsValid \u0026\u0026 lastNameIsValid \u0026\u0026 emailIsValid,\n    resetHandlers: [resetFirstName, resetLastName, resetEmail],\n  });\n\n  const firstNameInputClasses = firstNameInputIsInValid\n    ? \"form-control invalid\"\n    : \"form-control\";\n  const lastNameInputClasses = lastNameInputIsInValid\n    ? \"form-control invalid\"\n    : \"form-control\";\n  const emailInputClasses = emailInputIsInValid\n    ? \"form-control invalid\"\n    : \"form-control\";\n\n  const onSubmit = (/**@type Event*/ e) =\u003e {\n    e.preventDefault();\n\n    if (!formIsValid) {\n      executeBlurHandlers();\n      return false;\n    }\n\n    console.log(\"SUBMIT\", {\n      firstName,\n      lastName,\n      email,\n    });\n    reset();\n  };\n\n  return (\n    \u003cform onSubmit={onSubmit}\u003e\n      \u003cdiv className=\"control-group\"\u003e\n        \u003cdiv className={firstNameInputClasses}\u003e\n          \u003clabel htmlFor=\"name\"\u003eFirst Name\u003c/label\u003e\n          \u003cinput\n            type=\"text\"\n            onChange={(/**@type Event */ e) =\u003e {\n              firstNameChangeHandler(e.target?.value);\n            }}\n            onBlur={() =\u003e {\n              firstNameBlurHandler();\n            }}\n            value={firstName}\n            id=\"name\"\n          /\u003e\n          {firstNameInputIsInValid \u0026\u0026 (\n            \u003cp className=\"error-text\"\u003eFirstame must not be empty.\u003c/p\u003e\n          )}\n        \u003c/div\u003e\n        \u003cdiv className={lastNameInputClasses}\u003e\n          \u003clabel htmlFor=\"name\"\u003eLast Name\u003c/label\u003e\n          \u003cinput\n            type=\"text\"\n            id=\"name\"\n            onChange={(/**@type Event */ e) =\u003e {\n              lastNameChangeHandler(e.target?.value);\n            }}\n            onBlur={() =\u003e {\n              lastNameBlurHandler();\n            }}\n            value={lastName}\n          /\u003e\n          {lastNameInputIsInValid \u0026\u0026 (\n            \u003cp className=\"error-text\"\u003eLastname must not be empty.\u003c/p\u003e\n          )}\n        \u003c/div\u003e\n      \u003c/div\u003e\n      \u003cdiv className={emailInputClasses}\u003e\n        \u003clabel htmlFor=\"name\"\u003eE-Mail Address\u003c/label\u003e\n        \u003cinput\n          type=\"text\"\n          id=\"name\"\n          onChange={(/**@type Event */ e) =\u003e {\n            emailChangeHandler(e.target?.value);\n          }}\n          onBlur={() =\u003e {\n            emailBlurHandler();\n          }}\n          value={email}\n        /\u003e\n        {emailInputIsInValid \u0026\u0026 (\n          \u003cp className=\"error-text\"\u003e\n            Email must not be empty and must be a valid email.\n          \u003c/p\u003e\n        )}\n      \u003c/div\u003e\n      \u003cdiv className=\"form-actions\"\u003e\n        \u003cbutton disabled={!formIsValid}\u003eSubmit\u003c/button\u003e\n      \u003c/div\u003e\n    \u003c/form\u003e\n  );\n};\n\nexport default BasicForm;\n```\n\nThank you, if this helped you i would appreciate you star the repo [Use-manage-form repo](https://github.com/onukwilip/use-manage-form.git)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonukwilip%2Fuse-manage-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonukwilip%2Fuse-manage-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonukwilip%2Fuse-manage-form/lists"}