Material UI (MUI) é uma biblioteca de componentes amplamente utilizada que implementa o sistema de design Material do Google. Ela oferece um conjunto diversificado de componentes de interface de usuário (UI) pré-construídos, que podem ser empregados para criar interfaces que sejam tanto funcionais quanto esteticamente agradáveis.
Embora tenha sido originalmente concebida para React, a sua versatilidade permite que seja integrada com outras estruturas dentro do ecossistema React, como o Next.js.
Primeiros passos com o React Hook Form e a interface Material UI
React Hook Form é uma biblioteca muito popular que simplifica a criação, gestão e validação de formulários através de uma abordagem declarativa.
Ao combinar os componentes de Material UI com os estilos, é possível criar formulários intuitivos e visualmente atraentes, mantendo um design consistente na sua aplicação Next.js.
Para começar, crie um projeto Next.js localmente. Para este guia, use a versão mais recente do Next.js, que utiliza o diretório App.
npx create-next-app@latest next-project --app
Em seguida, instale os seguintes pacotes no seu projeto:
npm install react-hook-form @mui/material @mui/system @emotion/react @emotion/styled
Aqui está uma amostra do resultado final:
O código deste projeto está disponível neste repositório GitHub.
Criação e estilização de formulários
O React Hook Form oferece várias funções auxiliares, incluindo o hook `useForm`.
Este hook simplifica a gestão do estado do formulário, a validação dos dados inseridos e o processo de envio, facilitando os aspetos fundamentais da administração de formulários.
Para criar um formulário que utilize este hook, adicione o seguinte código a um novo arquivo, por exemplo, `src/components/form.js`.
Comece por adicionar as importações necessárias dos pacotes React Hook Form e MUI:
"use client" import React, {useState} from 'react'; import { useForm } from 'react-hook-form'; import { TextField, Button as MuiButton, Alert } from '@mui/material'; import { styled } from '@mui/system';
A MUI disponibiliza um conjunto de componentes de interface de utilizador prontos a usar que podem ser personalizados adicionando propriedades de estilo.
No entanto, para maior flexibilidade e controlo sobre o design, pode-se usar o método `styled` para estilizar os elementos da interface com propriedades CSS. Neste caso, o estilo dos componentes principais do formulário são definidos: o contentor principal, o formulário em si e os campos de texto.
Logo abaixo das importações, adicione este código:
const FormContainer = styled('div')({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100vh', }); const StyledForm = styled('form')({ width: '80%', maxWidth: '400px', padding: '20px', borderRadius: '10px', border: '2px solid #1E3A8A', boxShadow: '0px 0px 10px rgba(0, 0, 0, 0.2)', backgroundColor: '#ffffff', textAlign: 'center', }); const StyledTextField = styled(TextField)({ marginBottom: '16px', width: '100%', });
É fundamental manter a base de código modular no desenvolvimento. Em vez de juntar todo o código num único ficheiro, é preferível definir e estilizar componentes personalizados em arquivos separados.
Isto permite importar e utilizar estes componentes em várias partes da aplicação, tornando o código mais organizado e fácil de manter.
Agora, defina o componente funcional:
export default function Form() { const { register, handleSubmit, formState: { errors } } = useForm(); return ( <> <FormContainer> <StyledForm> <StyledTextField label="Username" type="text" /> <StyledTextField label="Password" type="password" /> <MuiButton type="submit" variant="contained" color="primary" margin="5px" > Submit </MuiButton> </StyledForm> </FormContainer> <> ); }
Por fim, importe este componente no seu arquivo `app/page.js`. Remova todo o código Next.js padrão e substitua-o pelo seguinte:
import Form from 'src/components/Form' export default function Home() { return ( <main > <Form /> </main> ) }
Inicie o servidor de desenvolvimento e verá um formulário básico com dois campos de entrada e um botão de envio no seu navegador.
Gerenciamento da validação do formulário
O formulário parece ótimo, mas ainda não está funcional. Para torná-lo operacional, é necessário adicionar um código de validação. As funções do utilitário `useForm` serão úteis na gestão e validação dos dados introduzidos pelo utilizador.
Primeiro, defina a seguinte variável de estado para gerir o estado atual do formulário, dependendo se o utilizador forneceu as credenciais corretas. Adicione este código dentro do componente funcional:
const [formStatus, setFormStatus] = useState({ success: false, error: '' });
Em seguida, crie uma função manipuladora para validar as credenciais. Esta função irá simular um pedido à API HTTP, que normalmente ocorre quando as aplicações cliente interagem com uma API de autenticação back-end.
const onSubmit = (data) => { if (data.username === 'testuser' && data.password === 'password123') { setFormStatus({ success: true, error: '' }); } else { setFormStatus({ success: false, error: 'Invalid username or password' }); } };
Adicione uma função de manipulador de eventos `onClick` ao componente do botão – passando-o como uma propriedade – para acionar a função `onSubmit` quando um utilizador clica no botão de envio.
onClick={handleSubmit(onSubmit)}
O valor da variável de estado `formStatus` é importante, pois determinará como será dado feedback ao utilizador. Se o utilizador inserir as credenciais corretas, será apresentada uma mensagem de sucesso. Se existissem outras páginas na sua aplicação Next.js, poderia redirecionar o utilizador para uma página diferente.
Também é necessário fornecer feedback adequado se as credenciais estiverem erradas. O Material UI oferece um ótimo componente de feedback que pode ser usado em conjunto com a técnica de renderização condicional do React para informar o utilizador, com base no valor de `formStatus`.
Para isso, adicione o seguinte código logo abaixo da tag de abertura `StyledForm`.
{formStatus.success ? ( <Alert severity="success">Form submitted successfully</Alert> ) : formStatus.error ? ( <Alert severity="error">{formStatus.error}</Alert> ) : null}
Agora, para capturar e validar a entrada do utilizador, pode usar a função `register` para registar os campos de entrada do formulário, rastrear os seus valores e especificar regras de validação.
Esta função recebe vários argumentos, incluindo o nome do campo de entrada e um objeto com parâmetros de validação. Este objeto especifica as regras de validação do campo de entrada, como um padrão específico e um comprimento mínimo.
Adicione o seguinte código como uma propriedade no componente `StyledTextField` do nome de utilizador.
{...register('username', { required: 'Username required', pattern: { value: /^[a-zA-Z0-9_.-]*$/, message: 'Invalid characters used' }, minLength: { value: 6, message: 'Username must be at least 6 characters' }, })}
Agora, adicione o seguinte objeto como uma propriedade no componente `StyledTextField` da palavra-passe.
{...register('password', { required: 'Password required', minLength: { value: 8, message: 'Password must be at least 8 characters' }, })}
Adicione o seguinte código abaixo do campo de entrada do nome de utilizador para fornecer feedback visual sobre os requisitos de entrada.
Este código irá acionar um alerta com uma mensagem de erro para informar o utilizador sobre os requisitos, e certificar-se de que corrige quaisquer erros antes de enviar o formulário.
{errors.username && <Alert severity="error">{errors.username.message}</Alert>}
Por fim, inclua um código semelhante logo abaixo do campo de texto da palavra-passe:
{errors.password && <Alert severity="error">{errors.password.message}</Alert>}
Excelente! Com estas mudanças, deverá ter um formulário funcional e visualmente apelativo, feito com React Hook Form e Material UI.
Melhore o seu desenvolvimento Next.js com bibliotecas do lado do cliente
Material UI e React Hook Form são apenas dois exemplos das muitas bibliotecas excelentes do lado do cliente que podem ser usadas para acelerar o desenvolvimento front-end do Next.js.
As bibliotecas do lado do cliente fornecem recursos prontos para produção e componentes pré-construídos que ajudam a construir melhores aplicações front-end de forma mais rápida e eficiente.