├── .babelrc ├── .eslintignore ├── .eslintrc ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── FUNDING.yml ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── lock.yml ├── .gitignore ├── .prettierrc ├── .travis.yml ├── LICENSE ├── README.md ├── banner.png ├── package-lock.json ├── package-scripts.js ├── package.json ├── rollup.config.js ├── scripts └── postinstall.js ├── src ├── index.d.ts ├── index.js ├── internal │ ├── shallowEqual.js │ └── shallowEqual.test.js ├── useField.js ├── useField.test.js ├── useForm.js ├── useForm.test.js ├── useFormState.js └── useFormState.test.js └── tsconfig.json /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "loose": true, 7 | "targets": { 8 | "node": "8" 9 | } 10 | } 11 | ], 12 | "@babel/preset-react" 13 | ], 14 | 15 | "plugins": [ 16 | "@babel/plugin-syntax-dynamic-import", 17 | "@babel/plugin-syntax-import-meta", 18 | "@babel/plugin-proposal-class-properties", 19 | "@babel/plugin-proposal-json-strings", 20 | [ 21 | "@babel/plugin-proposal-decorators", 22 | { 23 | "legacy": true 24 | } 25 | ], 26 | "@babel/plugin-proposal-function-sent", 27 | "@babel/plugin-proposal-export-namespace-from", 28 | "@babel/plugin-proposal-numeric-separator", 29 | "@babel/plugin-proposal-throw-expressions" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | dist 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app", 3 | "plugins": ["react-hooks"], 4 | "rules": { 5 | "jsx-a11y/href-no-hash": 0, 6 | "react-hooks/rules-of-hooks": "error", 7 | "react-hooks/exhaustive-deps": "warn" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of 9 | experience, nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or reject 41 | comments, commits, code, wiki edits, issues, and other contributions that are 42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any 43 | contributor for other behaviors that they deem inappropriate, threatening, 44 | offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at rasmussenerik@gmail.com. The project 59 | team will review and investigate all complaints, and will respond in a way that 60 | it deems appropriate to the circumstances. The project team is obligated to 61 | maintain confidentiality with regard to the reporter of an incident. Further 62 | details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 71 | version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thanks for your interest in contributing to 🏁 React Final Form Hooks! Please take a 4 | moment to review this document **before submitting a pull request**. 5 | 6 | We are open to, and grateful for, any contributions made by the community. 7 | 8 | ## Reporting issues and asking questions 9 | 10 | Before opening an issue, please search 11 | the [issue tracker](https://github.com/final-form/react-final-form-hooks/issues) to 12 | make sure your issue hasn’t already been reported. 13 | 14 | **We use the issue tracker to keep track of bugs and improvements** to 🏁 React 15 | Final Form Hooks itself, its examples, and the documentation. We encourage you to open 16 | issues to discuss improvements, architecture, internal implementation, etc. If a 17 | topic has been discussed before, we will ask you to join the previous 18 | discussion. 19 | 20 | For support or usage questions, please search and ask on 21 | [StackOverflow with a `react-final-form-hooks` tag](https://stackoverflow.com/questions/tagged/react-final-form-hooks). 22 | We ask you to do this because StackOverflow has a much better job at keeping 23 | popular questions visible. Unfortunately good answers get lost and outdated on 24 | GitHub. 25 | 26 | **If you already asked at StackOverflow and still got no answers, post an issue 27 | with the question link, so we can either answer it or evolve into a bug/feature 28 | request.** 29 | 30 | ## Sending a pull request 31 | 32 | **Please ask first before starting work on any significant new features.** 33 | 34 | It's never a fun experience to have your pull request declined after investing a 35 | lot of time and effort into a new feature. To avoid this from happening, we 36 | request that contributors create 37 | [an issue](https://github.com/final-form/react-final-form-hooks/issues) to first 38 | discuss any significant new features. 39 | 40 | Please try to keep your pull request focused in scope and avoid including 41 | unrelated commits. 42 | 43 | After you have submitted your pull request, we’ll try to get back to you as soon 44 | as possible. We may suggest some changes or improvements. 45 | 46 | Please format the code before submitting your pull request by running: 47 | 48 | ```sh 49 | npm run precommit 50 | ``` 51 | 52 | ## Coding standards 53 | 54 | Our code formatting rules are defined in 55 | [.eslintrc](https://github.com/final-form/react-final-form-hooks/blob/master/.eslintrc). 56 | You can check your code against these standards by running: 57 | 58 | ```sh 59 | npm start lint 60 | ``` 61 | 62 | To automatically fix any style violations in your code, you can run: 63 | 64 | ```sh 65 | npm run precommit 66 | ``` 67 | 68 | ## Running tests 69 | 70 | You can run the test suite using the following commands: 71 | 72 | ```sh 73 | npm test 74 | ``` 75 | 76 | Please ensure that the tests are passing when submitting a pull request. If 77 | you're adding new features to 🏁 React Final Form Hooks, please include tests. 78 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: erikras 4 | patreon: erikras 5 | open_collective: final-form 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with a single custom sponsorship URL 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | ### Are you submitting a **bug report** or a **feature request**? 8 | 9 | 10 | 11 | ### What is the current behavior? 12 | 13 | 14 | 15 | ### What is the expected behavior? 16 | 17 | ### Sandbox Link 18 | 19 | 20 | 21 | ### What's your environment? 22 | 23 | 24 | 25 | ### Other information 26 | 27 | 28 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | # Configuration for lock-threads - https://github.com/dessant/lock-threads 2 | 3 | # Number of days of inactivity before a closed issue or pull request is locked 4 | daysUntilLock: 365 5 | 6 | # Issues and pull requests with these labels will not be locked. Set to `[]` to disable 7 | exemptLabels: [] 8 | 9 | # Label to add before locking, such as `outdated`. Set to `false` to disable 10 | lockLabel: false 11 | 12 | # Comment to post before locking. Set to `false` to disable 13 | lockComment: > 14 | This thread has been automatically locked since there has not been 15 | any recent activity after it was closed. Please open a new issue for 16 | related bugs. 17 | 18 | # Limit to only `issues` or `pulls` 19 | # only: issues 20 | 21 | # Optionally, specify configuration settings just for `issues` or `pulls` 22 | # issues: 23 | # exemptLabels: 24 | # - help-wanted 25 | # lockLabel: outdated 26 | 27 | pulls: 28 | daysUntilLock: 30 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.iml 3 | .nyc_output 4 | coverage 5 | flow-coverage 6 | node_modules 7 | dist 8 | lib 9 | es 10 | npm-debug.log 11 | .DS_Store 12 | yarn.lock 13 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | semi: false 2 | singleQuote: true 3 | trailingComma: none 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | before_install: 4 | - npm install -g npm@6.7.0 5 | cache: 6 | directories: 7 | - node_modules 8 | notifications: 9 | email: false 10 | node_js: 11 | - '9' 12 | - '10' 13 | - 'stable' 14 | script: 15 | - npm start validate 16 | after_success: 17 | - npx codecov 18 | branches: 19 | only: 20 | - master -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Erik Rasmussen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🏁 React Final Form Hooks 2 | 3 |  4 | 5 | [](#backers) [](#sponsors) [](https://www.npmjs.com/package/react-final-form-hooks) 6 | [](https://www.npmjs.com/package/react-final-form-hooks) 7 | [](https://travis-ci.org/final-form/react-final-form-hooks) 8 | [](https://codecov.io/gh/final-form/react-final-form-hooks) 9 | [](https://github.com/prettier/prettier) 10 | 11 | ✅ Zero dependencies 12 | 13 | ✅ Only peer dependencies: React and 14 | [🏁 Final Form](https://github.com/final-form/final-form#-final-form) 15 | 16 | ✅ Opt-in subscriptions - only update on the state you need! 17 | 18 | ✅ 💥 [**1.2 kB gzipped**](https://bundlephobia.com/result?p=react-final-form-hooks) 💥 19 | 20 | --- 21 | 22 | ## Installation 23 | 24 | ```bash 25 | npm install --save react-final-form-hooks final-form 26 | ``` 27 | 28 | or 29 | 30 | ```bash 31 | yarn add react-final-form-hooks final-form 32 | ``` 33 | 34 | ## Getting Started 35 | 36 | 🏁 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). 37 | 38 | #### ⚠️ This library will re-render your entire form on every state change, _as you type_. ⚠️ 39 | 40 | If 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. 41 | 42 | Here's what it looks like in your code: 43 | 44 | ```jsx 45 | import { useForm, useField } from 'react-final-form-hooks' 46 | 47 | const MyForm = () => { 48 | const { form, handleSubmit, values, pristine, submitting } = useForm({ 49 | onSubmit, // the function to call with your form values upon valid submit 50 | validate // a record-level validation function to check all form values 51 | }) 52 | const firstName = useField('firstName', form) 53 | const lastName = useField('lastName', form) 54 | return ( 55 |
74 | ) 75 | } 76 | ``` 77 | 78 | ## Table of Contents 79 | 80 | 81 | 82 | 83 | 84 | - [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) 85 | - [Examples](#examples) 86 | - [Simple Example](#simple-example) 87 | - [API](#api) 88 | - [`useField`](#usefield) 89 | - [`name : string`](#name--string) 90 | - [`form : Form`](#form--form) 91 | - [`validate? : (value:any) => any`](#validate--valueany--any) 92 | - [`subscription? : FieldSubscription`](#subscription--fieldsubscription) 93 | - [`useForm`](#useform) 94 | - [`onSubmit : (values:Object) => ?Object | Promise | void`](#onsubmit--valuesobject--object--promiseobject--void) 95 | - [`validate?: (values:Object) => Object | Promise