Fala, dev! Hoje vou falar um pouco sobre Formcat: uma lib que vem me ajudando muito a trabalhar com formulários em React.

Quem trabalha ou já trabalhou com React, em algum momento precisou criar formulários com validações, manipulações de estados (entre outros detalhes), e percebeu o quanto é custoso e, muitas vezes, acabamos perdendo um pouco de tempo em algo que era para ser simples.

Pois bem, Formcat busca facilitar a vida do desenvolvedor na hora de criar esses formulários e eu irei mostrar como.

O que é?

Formcat é uma lib para trabalhar na criação de formulários que foi construída usando a Context API do React e que mantém seu próprio state. Ela nos permite criar uma ou mais validações para um campo especifico, garante a validação do formulário e recupera os dados inputados, de forma bem simples. Tudo isso usando os Fields ja existentes no Formcat ou criando nossos próprios Fields.

Como usar?

Ok. Até aqui, eu escrevi bastante, mas ainda não disse nada, né? Então, vamos para a parte prática.
Primeiro de tudo, vamos instalar o Formcat:

yarn add formcat
# or
npm install --save formcat

Com a lib devidamente instalada, vamos criar nosso formulário. Ele será composto por um input do tipo text, um select, um radio, um textarea e um checkbox. Para isso, utilizaremos todos os Fields que vêm no Formcat. Depois ensinarei como criar um personalizado.

Vamos lá, esse será o código no nosso formulário

import { Form, Submit } from 'formcat'
import {
  InputField,
  TextField,
  SelectField,
  RadiosField,
  CheckboxField
} from "formcat/fields";

...

<Form onSubmit={handleSubmit}>
    <InputField 
        label="Nome" 
        name="nome" 
        required 
    />
    <SelectField
        label="Que tipo de dev você se considera?"
        name="dev"
        required
        options={[
            { label: "---", value: "" },
            { label: "Frontend", value: "frontend" },
            { label: "Backend", value: "backend" },
            { label: "Fullstack", value: "fullstack" },
            { label: "Outro", value: "outro" }
        ]}
    />
    <RadiosField
        label="Quanto tempo trabalha como dev?"
        name="tempo"
        required
        options={[
            { label: "1 - 3 anos", value: "1-3" },
            { label: "3 - 5 anos", value: "3-5" },
            { label: "+5 anos", value: "+5" }
        ]}
    />
    <TextField 
        label="Fale um pouco sobre você" 
        name="sobre" 
        rows="10" 
    />
    <CheckboxField
        label="Estou de acordo em enviar minha informações"
        name="deacordo"
        required
    />

    <Submit>Enviar</Submit>
</Form>

...

Bom, agora vou explicar tudo que usamos nesse formulário:

Form: É o nosso component principal. É ele que cria o contexto e guarda o estado do nosso formulário. Nesse caso, passamos apenas uma propriedade para ele: o onSubmit. Essa propriedade retorna os dados preenchidos no formulários. Porém, você pode ver todas as props que ele aceita clicando aqui.

InputField: É o nosso input=”text”

SelectField: É o nosso select, e ele recebe uma props options que define a lista de items que será exibida.

RadiosField: É o nosso input=”radio”, possui a mesma props options do SelectField para compor os radios.

TextField: É o nosso textarea

CheckboxField: É o nosso input=”checkbox”

Todos esses fields que usamos possuem uma props obrigatória, que é a prop name. Ela que irá definir o nome do campo registrado no contexto do formulário. Para saber sobre todas as propriedades que os Fields podem receber, basta olhar na documentação clicando aqui.

E, por fim, o component Submit, que é o component onde irá submeter nosso form. Porém, ele será habilitado apenas se o form estiver válido, ou seja, campos required que estejam vazios ou que possuam a props validations e não tenham o assert farão com que o botão submit fique desabilitado.

Mas, Guilherme… validations? Você não falou nada sobre isso! Pois é, vamos falar disso agora.

O Formcat nos permite validar qualquer campo integrado a ele utilizando a propriedade validations. Essa propriedade recebe uma lista de funções que retornam *true* ou *false* e só valida o campo se todas as funções retornarem *true*, ou seja, você pode criar quantas validações quiser para o mesmo campo.

Vamos para um exemplo:

Imagine que no campo *nome* do nosso formulário a gente precise que o usuário coloque, pelo menos, nome e sobrenome. Impedindo que ele coloque apenas o primeiro nome.

Nossa validação ficaria assim:

function hasMoreThanOne (value) {
    return value.trim().split(' ').length > 1;
}

...
    <InputField 
        label="Nome" 
        name="nome" 
        validations={[hasMoreThanOne]}
        required 
    />
...

Onde value será sempre o valor digitado no campo.

Caso queira entender um pouco mais sobre as validações, pode olhar a documentação clicando aqui.

Vamos ver abaixo como ficou nosso formulário funcionando.

Agora que eu ja entendi como usar os Fields do Formcat, eu quero criar os meus próprios fields. Como eu faço?

Vamos lá!

Criando Fields personalizados

Para criar os fields personalizados iremos usar um HOC chamado withContextForm e é bem simples. Criaremos um input=”text” simples como exemplo.

import { withFormContext } from 'formcat'

const Field = withFormContext(({ error, ...input }) => (
  <input {...input} />
))

Feito isso, ao usar o component Field dentro do Form ele já será integrado ao contexto. Você pode ver mais detalhes da criação de um campo customizável clicando aqui. Ou ver como o InputField foi criado, por exemplo, clicando aqui.

Podemos ver um exemplo abaixo de um formulário com campos personalizados, que se encontra na documentação

Bom galera, é isso… Espero que vocês tenham entendido, espero também que tenham gostado. Mas, principalmente, espero que o Formcat possa ajudar vocês da mesma forma que vem me ajudando… e, fiquem à vontade para contribuir.

Btw, esse é um ótimo projeto para quem quer contribuir em projetos opensource. Fique à vontade para mandar Pull Requests, criar Issues, dar o seu Star, e passar para o amigo.

Qualquer dúvida, podem me procurar. Vocês me encontram no twitter como @guilhermelouro ou no chat da Impulso como @guilherme-louro.