Criando formulários com UseForm
Tags: react, forms, hooks, useform
Published: 2020-06-09 18:10:18

Read this in English: https://react-useform.vercel.app

Em primeiro lugar gostaria de dizer que não tinha intenção de criar um pacote npm para lidar com formulários, pois acredito que somente o react com sua API de hooks consegue fazer isso muito bem, e ainda mais que a maioria dos pacotes de formulários não conseguem lidar com objetos complexos vindos do back-end, a maioria simplesmente planifica o objeto e faz com que eles percam suma anatomia. Em um cenário perfeito em que o back-end provem dados no formato mais fácil para o front-end isso não é um problema, mas quando se esta trabalhando com aplicações mais complexas e com a ideia de API First, isto é, partir do princípio que a API deve ser um dos focos principais ao construir um produto e desenhá-la visando desempenho e não necessariamente sob medida para um cliente específico (web, mobile, tv).

>[Get in touch with me on Twitter](https://twitter.com/juciano_barbosa)

Se quiser saber mais sobre API First leia em https://sensedia.com/api/o-que-e-uma-estrategia-api-first/.

Nesse cenário você como desenvolvedor front-end deve trabalhar nos dados muito mais para compor uma tela.

No último produto que trabalhei senti a necessidade de criar e gerenciar formulários que continham objetos de várias camadas e listas, e que não me obrigasse a usar a tag “form” sempre, oque dificulta quando quero ter formulários com vários steps, e que também não me traga feedback de algum campo preenchido errado somente depois de tentar enviar o formulário, isso é muito chato e cansativo, apesar de performático.
Foi nesse momento que me ocorreu a ideia de criar um hook que tornasse isso mais simples e ainda mantivesse um bom desempenho.
Se você achar o projeto interessante visite o repositório e sinta-se a vontade para dar um feedback, abrir um PR ou compartilhar.

### Lei a documentação https://www.useform.org/

### Fork Repositório https://github.com/Jucian0/useform

## Como funciona `useForm`?

React Data Forms possui dois hooks, useForm e useValidation, useValidation é opcional. O código é escrito em typescript.
Hook useForm
useForm recebe um objeto com as seguintes propriedades opcionais:

- initialValues: como o nome sugere essa propriedade recebe os valores iniciais do objeto.
- debounce: essa opção aceita um valor numérico que corresponde ao periodo que ocorre entre o dado ser salvo no estado do formulário e o último evento de “input”.
- onChange: essa opção aceita um valor booliano e sinaliza que o formulário é do tipo controlado.
- validation: essa opção aceita um objeto de validação construído pelo Yup.

## Com useForm é possível criar formulários dos tipos

- controlled: que atualiza o estado do componente a cada mudança no input.
- debounce: que reduz drasticamente o número de mudanças no estado do formulário, já que só realiza a mudança se for percorrido um determinado tempo desde a última ocorrência do evento de “input”.
- uncontrolled: para usar esse formulário basta omitir as outras opções no objeto que useForm recebe. `useForm({})`

## Registrando um input

Alguns do recursos presentes no array devolvido pelo useForm são input e custom, essas funções são responsáveis por registrar entrada de dados, sendo input para elementos nativos do jsx como reww textare, input, select … para componentes como,datepicker e react-select

```jsx
   <input {...input({name:"input-name", type:"text", required:true ....})}>
                     /*or*/
   <input {...input("input-name", "text")}>
```

## Outros recursos

UseForm também disponibiliza funções para submit de formulário do tipo uncontrolled e funções para fazer reset em inputs específicos ou todos os inputs, é importante salientar que o reset deixa os inputs com os valores iniciais, se nenhum valor foi definido ao criar o formulário os inputs ficam vazios.
Criando um formulário do tipo debounce
Para criar um formulário é muito simples, e como dito anteriormente não é necessário ter um objeto com valores iniciais e o restante das opções são opcionais de acordo com o formulário que se pretende criar.

Neste exemplo vou ter um valor inicial, e vou criar uma validação, lembre-se que como o formulário é debounce e a validação ocorre sempre que o estado do objeto muda, neste exemplo a mensagem de erro aparece em um intervalo de 0.3 segundos.
Como o React Data Forms usa dot notation é possível utilizar qualquer objeto, ou propriedades em qualquer nível.
```jsx 
<input {...input("property.other.0.name...")}/>
```

```jsx

const initialValues = {
      name:"Jesse",
      email:"jesse@jesse.com",
      pets:["felix"],
      accept:false

   }

   const validation = yup.object().shape({
      name: yup.string().required("This field is required"),
      email: yup.string().email("This field must be a valid e-mail").required("This field is required"),
      pets: yup.array(yup.string().required("This field is required")),
      accept:yup.bool().oneOf([true], 'Field must be checked')
   })

   function ControlledForm(){

      const [{values, reset},{input}] = useForm({debounce:300, initialValues, validation})
      return (
         <>
            <input {...input("name", "text")}/>
            <span>{touched.name && errors.name}</span>
            <input {...input("email" ,"email")}/>   
            <span>{touched.email && errors.email}</span>         
            <input {...input("pets.0" ,"text")}/>     
            <span>{touched.pets?.[0] && errors.pets?.[0]}</span>    
            <input {...input("accept", "checkbox")}/>
            <span>{touched.accept && errors.accept}</span>    
         </>   
      )
   }
```

## CodeSandbox examplo:
 https://codesandbox.io/s/react-data-forms-2u2ju?from-embed

## Documentação oficial
A documentação ainda esta sendo construída e todas as contribuições são bem-vindas.