{"id":13826664,"url":"https://github.com/final-form/react-final-form-hooks","last_synced_at":"2025-07-09T01:31:02.350Z","repository":{"id":41403747,"uuid":"156075453","full_name":"final-form/react-final-form-hooks","owner":"final-form","description":"React Hooks to bind to 🏁 Final Form's high performance subscription-based form state management engine","archived":false,"fork":false,"pushed_at":"2023-01-03T15:18:42.000Z","size":2327,"stargazers_count":471,"open_issues_count":36,"forks_count":19,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-30T00:54:43.711Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/final-form.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"erikras","patreon":"erikras","open_collective":"final-form","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-11-04T11:33:31.000Z","updated_at":"2024-05-16T17:25:04.000Z","dependencies_parsed_at":"2023-02-01T07:00:38.616Z","dependency_job_id":null,"html_url":"https://github.com/final-form/react-final-form-hooks","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/final-form%2Freact-final-form-hooks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/final-form%2Freact-final-form-hooks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/final-form%2Freact-final-form-hooks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/final-form%2Freact-final-form-hooks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/final-form","download_url":"https://codeload.github.com/final-form/react-final-form-hooks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223748700,"owners_count":17196085,"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-08-04T09:01:42.186Z","updated_at":"2024-11-20T05:30:57.994Z","avatar_url":"https://github.com/final-form.png","language":"JavaScript","funding_links":["https://github.com/sponsors/erikras","https://patreon.com/erikras","https://opencollective.com/final-form"],"categories":["JavaScript"],"sub_categories":[],"readme":"# 🏁 React Final Form Hooks\n\n![React Final Form Hooks](banner.png)\n\n[![Backers on Open Collective](https://opencollective.com/final-form/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/final-form/sponsors/badge.svg)](#sponsors) [![NPM Version](https://img.shields.io/npm/v/react-final-form-hooks.svg?style=flat)](https://www.npmjs.com/package/react-final-form-hooks)\n[![NPM Downloads](https://img.shields.io/npm/dm/react-final-form-hooks.svg?style=flat)](https://www.npmjs.com/package/react-final-form-hooks)\n[![Build Status](https://travis-ci.org/final-form/react-final-form-hooks.svg?branch=master)](https://travis-ci.org/final-form/react-final-form-hooks)\n[![codecov.io](https://codecov.io/gh/final-form/react-final-form-hooks/branch/master/graph/badge.svg)](https://codecov.io/gh/final-form/react-final-form-hooks)\n[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n\n✅ Zero dependencies\n\n✅ Only peer dependencies: React and\n[🏁 Final Form](https://github.com/final-form/final-form#-final-form)\n\n✅ Opt-in subscriptions - only update on the state you need!\n\n✅ 💥 [**1.2 kB gzipped**](https://bundlephobia.com/result?p=react-final-form-hooks) 💥\n\n---\n\n## Installation\n\n```bash\nnpm install --save react-final-form-hooks final-form\n```\n\nor\n\n```bash\nyarn add react-final-form-hooks final-form\n```\n\n## Getting Started\n\n🏁 React Final Form Hooks is the leanest possible way to connect 🏁 Final Form to React, to acheive subscriptions-based form state management using the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern).\n\n#### ⚠️ This library will re-render your entire form on every state change, _as you type_. ⚠️\n\nIf performance is your goal, you are recommended to use [🏁 React Final Form](https://github.com/final-form/react-final-form). Also, that library does many other things for you, like managing checkbox and radio buttons properly. RFFHooks leaves all of that work to you. By default, 🏁 React Final Form Hooks subscribes to _all_ changes, but if you want to fine tune your form, you may specify only the form state that you care about for rendering your gorgeous UI.\n\nHere's what it looks like in your code:\n\n```jsx\nimport { useForm, useField } from 'react-final-form-hooks'\n\nconst MyForm = () =\u003e {\n  const { form, handleSubmit, values, pristine, submitting } = useForm({\n    onSubmit, // the function to call with your form values upon valid submit\n    validate // a record-level validation function to check all form values\n  })\n  const firstName = useField('firstName', form)\n  const lastName = useField('lastName', form)\n  return (\n    \u003cform onSubmit={handleSubmit}\u003e\n      \u003cdiv\u003e\n        \u003clabel\u003eFirst Name\u003c/label\u003e\n        \u003cinput {...firstName.input} placeholder=\"First Name\" /\u003e\n        {firstName.meta.touched \u0026\u0026 firstName.meta.error \u0026\u0026 (\n          \u003cspan\u003e{firstName.meta.error}\u003c/span\u003e\n        )}\n      \u003c/div\u003e\n      \u003cdiv\u003e\n        \u003clabel\u003eLast Name\u003c/label\u003e\n        \u003cinput {...lastName.input} placeholder=\"Last Name\" /\u003e\n        {lastName.meta.touched \u0026\u0026 lastName.meta.error \u0026\u0026 (\n          \u003cspan\u003e{lastName.meta.error}\u003c/span\u003e\n        )}\n      \u003c/div\u003e\n      \u003cbutton type=\"submit\" disabled={pristine || submitting}\u003e\n        Submit\n      \u003c/button\u003e\n    \u003c/form\u003e\n  )\n}\n```\n\n## Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [What's the difference between `react-final-form-hooks` and the hooks introduced in `react-final-form v5`?](#whats-the-difference-between-react-final-form-hooks-and-the-hooks-introduced-in-react-final-form-v5)\n- [Examples](#examples)\n  - [Simple Example](#simple-example)\n- [API](#api)\n  - [`useField`](#usefield)\n    - [`name : string`](#name--string)\n    - [`form : Form`](#form--form)\n    - [`validate? : (value:any) =\u003e any`](#validate--valueany--any)\n    - [`subscription? : FieldSubscription`](#subscription--fieldsubscription)\n  - [`useForm`](#useform)\n    - [`onSubmit : (values:Object) =\u003e ?Object | Promise\u003c?Object\u003e | void`](#onsubmit--valuesobject--object--promiseobject--void)\n    - [`validate?: (values:Object) =\u003e Object | Promise\u003cObject\u003e`](#validate-valuesobject--object--promiseobject)\n- [Contributors](#contributors)\n- [Backers](#backers)\n- [Sponsors](#sponsors)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## What's the difference between `react-final-form-hooks` and the hooks introduced in `react-final-form v5`?\n\nGreat question. The TL;DR is this:\n\n- `react-final-form-hooks` is a lightweight, simple solution for quickly getting a form up and running _in a single render function_, but allows for no performance optimization.\n- `react-final-form v5` is a more robust, battle-tested solution that involves creating more components and structure around your form.\n\n`react-final-form-hooks` does not put the `form` instance into the React context, but rather forces you to pass the `form` instance to `useField` so that the field can register itself with the form. This allows you to create your entire form in a single functional component, like the `MyForm` example above. It will also, by necessity, rerender your entire form on every value change.\n\n`react-final-form v5` requires that you wrap your entire form in a `\u003cForm\u003e` component that provides the `form` instance via context to its descendants. This means that you cannot use `useField` in the same function that is rendering your `\u003cForm\u003e`, because `useField` must be inside the `\u003cForm\u003e`.\n\n**Conclusion**: If your app has a couple of small (\u003c 20 inputs) forms where you aren't doing anything fancy with reusable custom input components, `react-final-form-hooks` might be all you need. But if your app is bigger and more sophisticated, or you need to optimize for performance, you should probably use `react-final-form`.\n\n## Examples\n\n### [Simple Example](https://codesandbox.io/s/r4j042m694)\n\nShows how to create fields and attach them to `\u003cinput/\u003e` elements.\n\n## API\n\nThe following can be imported from `react-final-form-hooks`.\n\n### `useField`\n\nReturns an object similar to [`FieldRenderProps`](https://github.com/final-form/react-final-form#fieldrenderprops).\n\n`useField` takes four parameters:\n\n#### `name : string`\n\n\u003e The name of the field. Required.\n\n#### `form : Form`\n\n\u003e The object returned from `useForm`. Required.\n\n#### `validate? : (value:any) =\u003e any`\n\n\u003e A field-level validation function that takes the current value and returns `undefined` if it is valid, or the error if it is not. Optional.\n\n#### `subscription? : FieldSubscription`\n\n\u003e A subscription of which parts of field state to be notified about. See [`FieldSubscription`](https://github.com/final-form/final-form#fieldsubscription--string-boolean-). Optional.\n\n### `useForm`\n\nReturns an object similar to [`FormRenderProps`](https://github.com/final-form/react-final-form#formrenderprops).\n\n`useForm` takes two parameters:\n\n#### `onSubmit : (values:Object) =\u003e ?Object | Promise\u003c?Object\u003e | void`\n\nSee [🏁 Final Form's `onSubmit` docs](https://github.com/final-form/final-form#onsubmit-values-object-form-formapi-callback-errors-object--void--object--promiseobject--void) for more information. Required.\n\n#### `validate?: (values:Object) =\u003e Object | Promise\u003cObject\u003e`\n\nA record level validation function. See [🏁 Final Form's `validate` docs](https://github.com/final-form/final-form#validate-values-object--object--promiseobject) for more information. Optional.\n\n---\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](.github/CONTRIBUTING.md)].\n\u003ca href=\"https://github.com/final-form/react-final-form-hooks/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/final-form/contributors.svg?width=890\" /\u003e\u003c/a\u003e\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/final-form#backer)]\n\n\u003ca href=\"https://opencollective.com/final-form#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/final-form#sponsor)]\n\n\u003ca href=\"https://opencollective.com/final-form/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/final-form/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/final-form/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinal-form%2Freact-final-form-hooks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffinal-form%2Freact-final-form-hooks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffinal-form%2Freact-final-form-hooks/lists"}