Como construir formulários usando React Hook Form e Yup com ChakraUI
Ivan Trindade
Posted on December 22, 2022
Em HTML, é o comportamento padrão dos formulários redirecionar para uma nova página sempre que são enviados. Portanto, para fornecer funcionalidade dinâmica, o React usa uma estratégia chamada componentes controlados.
Se você fez recentemente um curso de React, provavelmente não gostou desta parte, porque há muitos estados para gerenciar se você tiver vários inputs.
Primeiramente, você rastreia o estado do input usando a propriedade onChange que chama a função useState(). Os inputs são agrupados em torno de um elemento de formulário.
Quando o usuário envia o formulário, ele aciona a propriedade onClick ou onSubmit para definir as entradas para uma array contendo valores ou objetos, dependendo do número de inputs.
Em seguida, vem a validação, que verifica se o usuário inseriu alguma entrada. Caso contrário, retorne um erro, solicitando que o usuário insira uma entrada válida.
A lógica aqui é um monte de clichê. Você pode ficar entediado só de ouvir sobre o processo.
E se eu te disser que uma única biblioteca pode conseguir tudo isso?
1. O que é React-Hook-Form?
2. Como o React-Hook-Form afeta o desempenho
3. Como obter dados do usuário de um formulário
4. Como adicionar validação aos seus formulários com Yup
5. Como obter dados do usuário em um formulário que utiliza bibliotecas externas
O que é React-Hook-Form?
React Hook Form é uma biblioteca flexível que cuida de toda a sua validação, gerenciamento de estado e dados do usuário - e está tudo compactado em um tamanho de apenas 25,3kb (descompactado) e 9,1kb GZip (alterações com versões).
É simples e direto de usar, e você precisa escrever um código mínimo.
Uma das características que me impressiona, é o seu desempenho. Conforme mencionado em seu Site oficial, React-Hook-Form:
Minimiza o número de re-renderizações e montagem mais rápida, esforçando-se para fornecer a melhor experiência do usuário.
Como o React-Hook-Form afeta o desempenho
Se você estiver utilizando as versões anteriores da biblioteca, a documentação geralmente faz referência á propriedade ref para manipular o gerenciamento e a validação do estado.
<input type=”password” placeholder=”Password” ref={register} />
Dessa forma, o React-Hook-Form adota um método de entrada descontrolada, em vez de alterar o estado todas as vezes. Ele isola o componente selecionado e evita a renderização dos componentes filhos.
Isso reduz significamente o número de novas renderizações e aumenta o desempenho geral da aplicação.
Como obter dados do usuário de um formulário
E aqui está o que estaremos construindo. É um formulário simples com validação.
Eu criei um Codesandbox para este tutorial específico, portanto, certifique-se de consultá-lo caso se perca.
Aqui está o que você precisa acompanhar:
Primeiro, vamos instalar as dependências:
Com npm:
npm i react-hook-form @chakra-ui/react @emotion/react @emotion/styled @hookform/resolvers yup
Com yarn:
yarn add react-hook-form @chakra-ui/react @emotion/react @emotion/styled @hookform/resolvers yup
Primeiro vamos fazer as importações:
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { useForm } from "react-hook-form";
Crie as tipagens dos dados que serão enviados nos inputs:
type Form = {
name: string;
lastName: string;
sex: string;
};
Desestruture as seguintes constantes do hook useForm e atribua o schema com as validações ao resolver do useForm:
const { register, formState, control, handleSubmit } = useForm();
Desestruture as constantes errors e isSubmitting de formState:
const { errors, isSubmitting } = formState;
Usaremos a constante errors para acessar a mensagem de erro retornada do schema de validações. Por último, usaremos o isSubmitting na propriedade isLoading do botão do Chakra, para aparecer um spinner de carregamento enquanto o formulário está sendo enviado.
Crie um formulário simples como este:
<Flex as="form" onSubmit={handleSubmit(handleSend)}>
<FormControl isInvalid={!!errors}>
<Stack>
<Input
type="text"
name="name"
placeholder="Nome"
ref={yup.ref}
{...register("name")}
/>
{!!errors &&
<FormErrorMessage>
{errors?.name?.message}
</FormErrorMessage>}
<Input
type="text"
name="lastname"
ref={yup.ref}
placeholder="Sobrenome"
{...register("lastname")}
/>
{!!errors && (
<FormErrorMessage>
{errors?.lastname?.message}
</FormErrorMessage>
)}
<Controller
control={control}
name="sex"
rules={{ required: true }}
render={({ field }) => (
<Stack>
<Text size="md" fontWeight={500}>
Sexo
</Text>
<RadioGroup color="gray.400" {...field}>
<Stack spacing={5} direction="row">
<Radio
colorScheme="blue"
value="Masculino"
isInvalid={errors.sex?.type === "required"}
>
Masculino
</Radio>
<Radio
colorScheme="blue"
value="Feminino"
isInvalid={errors.sex?.type === "required"}
>
Feminino
</Radio>
</Stack>
</RadioGroup>
{!!errors && (
<FormErrorMessage>
{errors?.sex?.message}
</FormErrorMessage>
)}
</Stack>
)}
/>
<Button type="submit" isLoading={isSubmitting}>
Enviar
</Button>
</Stack>
</FormControl>
</Flex>
Usamos a função register para fazer com que o valor seja validado e enviado no formulário:
<Input type="text" name="name" {...register("name")} />
Para enviar os dados, criamos a função handleSend. Para que ela funcione usando Typescript, você precisará usar a tipagem SubmitHandler do próprio React-Hook-Form, passando a tipagem dos dados do seu formulário:
const handleSend: SubmitHandler<Form> = async (values) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log({ submited: values });
};
Então passamos a função handleSend como parâmetro da função handleSubmit do próprio React-Hook-Form, para que os dados sejam enviados:
<Flex as="form" onSubmit={handleSubmit(handleSend)}>
{...}
</Flex>
Como adicionar validação aos seus formulários com Yup
Fazer validações nunca foi tão simples com o Yup, você pode fazer validações simples e complexas de forma extremamente expressiva.
Crie o schema com as validações:
const createFormSchema = yup.object({
name: yup.string().required("Você deve digitar seu nome"),
lastname: yup.string().required("Você deve digitar seu sobrenome"),
sex: yup.string().required("Insira o seu sexo")
});
Agora atribua o schema de validações no resolver do useForm:
const { register, formState, control, handleSubmit } = useForm({
mode: "onChange",
resolver: yupResolver(createFormSchema)
});
Usamos a constante errors para validar que caso exista alguma mensagem de validação, ela seja renderizada no componente FormErrorMessage do Chakra, veja o exemplo:
{!!errors &&
<FormErrorMessage>
{errors?.name?.message}
</FormErrorMessage>}
Como obter dados do usuário em um formulário que utiliza bibliotecas externas
Se você analisar o código acima, perceberá que usamos a função register para fazer com que o valor seja validado e enviado no formulário. Então por qual motivo não estamos utilizando-o para registrar e validar o valor dos Radios?
O React-Hook-Form foi construído para ser usado com um HTML tradicional, sem uma biblioteca externa como o ChakraUI ou qualquer outra biblioteca semelhante. Estamos usando inputs do tipo radio personalizados do Chakra, portanto o React-Hook-Form não conseguirá registrar o valor dessa forma.
Para solucionar este problema, o Chakra fornece o componente Controller, no qual podemos usá-lo para registrar e validar os valores de componentes que usamos de bibliotecas externas.
Obrigado por ler! ✨
É bom ver que você leu até aqui. Se você obteve algumas informações com este artigo, sinta-se à vontade para compartilhá-lo com sua comunidade e colegas de trabalho.
Eu falo sobre tecnologias da web e projetos de construção,
documentando ainda mais o processo de desenvolvimento para outros desenvolvedores fazerem referência. Se precisar de alguma orientação, não deixe de comentar aqui.
Posted on December 22, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 30, 2024