|
| 1 | +# React AJV Schema Hook |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +[use-ajv-form](https://github.com/agjs/use-ajv-form) is a custom React Hook that enables you to generate your form logic and validation based on [Ajv JSON Schema Validator](https://ajv.js.org/). |
| 6 | + |
| 7 | +It integrates seamlessly with any form and is completely agnostic from your form markup. It simply provides the state and validation. You choose how you want to present the errors and organise your forms. In simple words, it's completely decoupled from how your forms work, look and feel. |
| 8 | + |
| 9 | +# Why |
| 10 | + |
| 11 | +Validating forms manually is a painful process. Ajv solves that by not only providing validation based on valid JSON Schema Specification, but also, provides custom plugins and keywords that allow you to create your own custom validators. That means that you can extend your schema with infinite amount of validators, and keep your forms still purely depend on the schema, without introducing manual if statements all over the place. |
| 12 | + |
| 13 | +This library is used by all forms on [Programmer Network](https://programmer.network/) and is Open Sourced due to our amazing community on an official [Programmer Network Twitch Channel](https://twitch.tv/programmer_network). |
| 14 | + |
| 15 | +# Install |
| 16 | + |
| 17 | +`yarn add @programmer_network/use-ajv-form` |
| 18 | + |
| 19 | +or |
| 20 | + |
| 21 | +`npm install @programmer_network/use-ajv-form` |
| 22 | + |
| 23 | +# Usage |
| 24 | + |
| 25 | +[Codesandbox Live Demo](https://google.com) |
| 26 | + |
| 27 | +Let's start with a simple example. |
| 28 | + |
| 29 | +Let's create our form object. This object contains methods and state that our form will depend on. |
| 30 | + |
| 31 | +```javascript |
| 32 | +import { useAjvForm } from '@programmer_network/useAjvForm'; |
| 33 | + |
| 34 | +const initialState = { |
| 35 | + title: '', |
| 36 | + description: '', |
| 37 | +}; |
| 38 | + |
| 39 | +const schema = { |
| 40 | + type: 'object', |
| 41 | + required: ['title'], |
| 42 | + properties: { |
| 43 | + title: { |
| 44 | + type: 'string', |
| 45 | + }, |
| 46 | + description: { |
| 47 | + type: 'string', |
| 48 | + minLength: 20, |
| 49 | + errorMessages: { |
| 50 | + minLength: 'Description is too short. At least 20 characters expected.', |
| 51 | + }, |
| 52 | + }, |
| 53 | + }, |
| 54 | +}; |
| 55 | + |
| 56 | +const form = useAjvForm(initialState, schema); |
| 57 | +``` |
| 58 | + |
| 59 | +Then we create a onSubmit form handler that will call our validators. |
| 60 | + |
| 61 | +```js |
| 62 | +const handleSubmit = (event) => { |
| 63 | + event.preventDefault(); |
| 64 | + |
| 65 | + if (!form.isValid()) { |
| 66 | + // form is invalid, exit early |
| 67 | + // when this happens, our hook will update the fields that failed validation |
| 68 | + return; |
| 69 | + } |
| 70 | + |
| 71 | + // validation successful, call some API |
| 72 | + axios.post('someUrl', form.data); |
| 73 | +}; |
| 74 | +``` |
| 75 | + |
| 76 | +Generally, your own Input component takes a value and an error. If you are using component composition, this might look a bit different, but you get the point. |
| 77 | + |
| 78 | +```jsx |
| 79 | +// your custom input component |
| 80 | +const CustomInput = ({ value, error, name }) => { |
| 81 | + <input type="text" name={name} value={value} />; |
| 82 | + { |
| 83 | + error && <span>{error}</span>; |
| 84 | + } |
| 85 | +}; |
| 86 | +``` |
| 87 | + |
| 88 | +As you may notice, for every given property in your schema, our hook will create a value and error properties. Error property is initially set to null, and the value to whatever values are set in your initial state. |
| 89 | + |
| 90 | +```jsx |
| 91 | +<form onSubmit={handleSubmit}> |
| 92 | + <CustomInput name="title" value={form.state.title.value} /> |
| 93 | + <CustomInput name="description" value={form.state.description.value} /> |
| 94 | + <button type="submit">Submit</button> |
| 95 | +</form> |
| 96 | +``` |
0 commit comments