# react-joi

> State-based validation hook. Unlike other component/form based validations, `react-joi` allows to use native HTML elements & require no `` element to do your `submit` validation. In short, we don't mess with your DOM.

Latest version **1.3.1** (published 2023-05-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-joi
pnpm add react-joi
yarn add react-joi
bun add react-joi
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.3.1 |
| Published | 2023-05-16 |
| First published | 2021-01-14 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 15.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 4 |
| Author | Thiha Thit |
| Maintainers | thihathit |
| Keywords | react, react-hooks, hooks, joi, validation, form-validation |

## Links

- npm: https://www.npmjs.com/package/react-joi
- Repository: https://github.com/thihathit/react-joi
- Homepage: https://github.com/thihathit/react-joi#readme
- Issues: https://github.com/thihathit/react-joi/issues
- npm.io page: https://npm.io/package/react-joi

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.3.1 (latest) — 2023-05-16
- 1.3.0 — 2022-11-28
- 1.2.0 — 2022-09-02
- 1.1.0 — 2022-06-19
- 1.0.1 — 2022-03-22
- 1.0.0 — 2021-11-13
- 1.0.0-alpha.2 — 2021-11-13
- 1.0.0-alpha.1 — 2021-11-13
- 1.0.0-alpha.0 — 2021-08-22
- 0.0.6 — 2021-04-28
- 0.0.5 — 2021-01-19
- 0.0.4 — 2021-01-18
- 0.0.3 — 2021-01-14
- 0.0.2 — 2021-01-14
- 0.0.1 — 2021-01-14

## README

## About

State-based validation hook. Unlike other component/form based validations, `react-joi` allows to use native HTML elements & require no `<form />` element to do your `submit` validation. In short, we don't mess with your DOM.

The core validator uses [Joi](https://joi.dev/) as in it's name.

## Installation

install package via [npm](https://www.npmjs.com/package/react-joi).

install [joi](https://joi.dev/).

```
yarn add react-joi

// or

npm i react-joi
```

## Usage

```jsx
import Joi from "joi"
import { useValidator } from "react-joi"

function App() {
    const { state, setData, setExplicitField, validate } = useValidator({
        initialData: {
            name: null,
            email: null,
        },
        schema: Joi.object({
            name: Joi.string().required(),
            email: Joi.string()
                .email({
                    tlds: { allow: false },
                })
                .required(),
        }),
        explicitCheck: {
            name: false,
            email: false,
        },
        validationOptions: {
            abortEarly: true,
        },
    })

    const updateName = (e) => {
        // react < v17
        e.persist()

        setData((old) => ({
            ...old,
            name: e.target.value,
        }))
    }

    const updateEmail = (e) => {
        // react < v17
        e.persist()

        setData((old) => ({
            ...old,
            email: e.target.value,
        }))
    }

    return (
        <div>
            <div>
                <label>Name</label>
                <br />
                <input
                    type="text"
                    onChange={updateName}
                    onBlur={() => setExplicitField("name", true)}
                />
                <br />
                {state.$errors.name.map((data) => data.$message).join(",")}

                <br />
                <br />

                <label>Email</label>
                <br />
                <input
                    type="text"
                    onChange={updateEmail}
                    onBlur={() => setExplicitField("email", true)}
                />
                <br />
                {state.$errors.email.map((data) => data.$message).join(",")}

                <br />
                <br />
                <br />

                <button onClick={validate}>Submit</button>
            </div>

            <br />
            <hr />
            <br />

            <code>
                <pre>{JSON.stringify(state, null, 2)}</pre>
            </code>
        </div>
    )
}
```

![](https://i.ibb.co/93wndgy/image.png)

Note that the **explicitCheck** object is **optional**, and is only needed if it is desired to suppress error messages during
input until the onBlur method has fired at least once. If this behavior is not required/desired, then omit it as shown
in the second example.

## Documentation

Type Doc: https://paka.dev/npm/react-joi/api

### State

| name                  | description                                                                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `$data`               | Values of the instance                                                                                                                                 |
| `$dirty`              | Dirty state of the instance                                                                                                                            |
| `$explicit_fields`    | Settings of any fields that have been explicitly set                                                                                                   |
| `$data_state`         | State of the values:`$dirty` means if the initial data is touched or not                                                                               |
| `$source_errors`      | Raw errors of the instance. This re-validates every time `$data` is changed regardless of `$dirty` is `true` or `false`                                |
| `$errors`             | `Recommended` way of retrieving errors of each fields. Each fields respects global `$dirty` state of the instance and `$data_state`'s `$dirty` states. |
| `$all_errors`         | List of all errors respecting `$dirty` states of their own and global state.                                                                           |
| `$all_source_errors`  | List of all errors not respecting `$dirty` states of their own and global state.                                                                       |
| `$invalid`            | Validity of the instance respecting global `$dirty`.                                                                                                   |
| `$auto_invalid`       | Validity of the instance not respecting global `$dirty`. `Recommended` use case for disabled submit button                                             |
| `$validation_success` | Positive validity of the instance respecting global `$dirty`.                                                                                          |
| `$validated`          | `true` when `validate()` function has been called. Resets to `false` whenever `$data` is changed.                                                      |

### Functions

| name               | description                                                         |
| ------------------ | ------------------------------------------------------------------- |
| `setData`          | Setting data/values, same as `useState`'s second argument function. |
| `setExplicitField` | Modify error suppression. `setExplicitField('field_name', boolean)` |
| `validate`         | Validate the data manually                                          |
| `reset`            | Resets all data/state to initial. Also reset errors.                |

### Combo with [react-use-models](https://www.npmjs.com/package/react-use-models).

```jsx
import React, { useEffect } from "react"

import useModels from "react-use-models"
import Joi from "joi"
import useValidator from "react-joi"

export default function App() {
    const { models, register } = useModels({
        defaultState: {
            name: "My Name",
            email: "",
        },
    })

    const { state, setData, validate } = useValidator({
        initialData: models,
        schema: Joi.object({
            name: Joi.string().required(),
            email: Joi.string()
                .email({
                    tlds: { allow: false },
                })
                .required(),
        }),
    })

    // Sync model <-> validator
    useEffect(() => {
        setData(models)
    }, [models])

    return (
        <div>
            <label>Name</label>
            <br />
            <input {...register.input({ name: "name" })} />
            <br />
            {state.$errors.name.map((data) => data.$message).join(",")}

            <br />
            <br />

            <label>Email</label>
            <br />
            <input {...register.input({ name: "email" })} />
            <br />
            {state.$errors.email.map((data) => data.$message).join(",")}

            <br />

            <button onClick={validate}>Submit</button>

            <code>
                <h2>Models</h2>
                <pre>{JSON.stringify(models, null, 2)}</pre>
            </code>

            <hr />

            <code>
                <h2>Validation</h2>
                <pre>{JSON.stringify(state, null, 2)}</pre>
            </code>
        </div>
    )
}
```

---
_Source: https://npm.io/package/react-joi · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
