Створюйте стильні форми Next.js за допомогою React Hook Form і Material UI

Material UI (MUI) – це популярна бібліотека компонентів, що втілює принципи Google Material Design. Вона надає широкий набір готових елементів інтерфейсу, які допомагають створювати функціональні та візуально привабливі додатки.

Хоча MUI націлена на використання з React, її можна успішно інтегрувати з іншими фреймворками екосистеми React, як-от Next.js.

Початок роботи з React Hook Form та Material UI

React Hook Form – це відома бібліотека, що спрощує створення, управління та валідацію форм через декларативний підхід.

Поєднуючи компоненти Material UI та стилі, можна створювати естетично привабливі та зручні форми, а також забезпечити єдиний стиль в усьому вашому Next.js-додатку.

Для початку створіть новий проєкт Next.js на своєму комп’ютері. У цьому посібнику ми використаємо останню версію Next.js з каталогом App.

 npx create-next-app@latest next-project --app 

Далі, встановіть необхідні пакети:

 npm install react-hook-form @mui/material @mui/system @emotion/react @emotion/styled 

Ось як виглядатиме форма, яку ми створимо:

Повний код проєкту доступний на GitHub.

Створення та стилізація форм

React Hook Form пропонує ряд зручних інструментів, зокрема хук `useForm`.

Цей хук значно спрощує роботу зі станом форми, перевіркою даних та відправкою, що робить керування формами значно простішим.

Щоб створити форму, що використовує `useForm`, додайте наступний код у файл `src/components/form.js`.

Спершу, імпортуйте необхідні компоненти з React Hook Form та 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';

MUI надає готові до використання компоненти, які можна налаштувати за допомогою атрибутів стилю.

Однак, якщо вам потрібен більший контроль над дизайном, ви можете скористатися методом `styled` для стилізації елементів за допомогою CSS. У цьому прикладі ми стилізуємо основні компоненти форми: контейнер, саму форму та поля вводу.

Додайте цей код відразу після імпортів:

 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%',
});

Для підтримки структурованої кодової бази, компоненти краще визначати та стилізувати в окремих файлах.

Це дозволить легко імпортувати та використовувати ці компоненти в різних частинах вашого додатку, роблячи код організованішим та зручнішим для підтримки.

Тепер визначимо функціональний компонент:

 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>
    </>
  );
}

Далі, імпортуйте цей компонент у файл `app/page.js`. Видаліть весь код за замовчуванням та замініть його на:

 import Form from 'src/components/Form'

export default function Home() {
  return (
    <main >
      <Form />
    </main>
  )
}

Запустіть сервер розробки, і ви побачите базову форму з двома полями введення та кнопкою відправки у вашому браузері.

Обробка перевірки форми

Форма виглядає добре, але поки що нічого не робить. Для того, щоб зробити її функціональною, необхідно додати перевірку введених даних. Функції хука `useForm` стануть в нагоді для керування та валідації даних, введених користувачем.

Спершу визначимо змінну стану, щоб відстежувати поточний стан форми, залежно від того, чи правильно користувач ввів облікові дані. Додайте цей код до функціонального компонента:

 const [formStatus, setFormStatus] = useState({ success: false, error: '' }); 

Далі, створіть обробник для перевірки облікових даних. Ця функція імітує запит API, який зазвичай виникає під час взаємодії клієнта з сервером автентифікації.

 const onSubmit = (data) => {
    if (data.username === 'testuser' && data.password === 'password123') {
        setFormStatus({ success: true, error: '' });
    } else {
        setFormStatus({ success: false, error: 'Invalid username or password' });
    }
};

Додайте обробник `onClick` до компонента кнопки, передавши як проп `handleSubmit(onSubmit)`, щоб викликати функцію `onSubmit` при натисканні кнопки.

 onClick={handleSubmit(onSubmit)} 

Значення змінної `formStatus` важливе, оскільки визначає спосіб надання зворотного зв’язку користувачеві. Якщо користувач вводить правильні дані, можна показати повідомлення про успішне виконання. Якщо у вашому Next.js додатку є інші сторінки, можна перенаправити користувача на іншу сторінку.

Необхідно також надати відповідний відгук, якщо облікові дані невірні. Material UI пропонує чудовий компонент зворотного зв’язку, який можна використовувати разом з умовним рендерингом React, щоб інформувати користувача на основі значення `formStatus`.

Для цього, додайте наступний код відразу після відкриваючого тега `StyledForm`.

 {formStatus.success ? (
    <Alert severity="success">Form submitted successfully</Alert>
) : formStatus.error ? (
    <Alert severity="error">{formStatus.error}</Alert>
) : null}

Тепер, щоб зафіксувати та перевірити дані, введені користувачем, можна використовувати функцію `register` для реєстрації полів введення, відстеження їх значень та визначення правил валідації.

Ця функція приймає кілька аргументів, зокрема назву поля та об’єкт параметрів перевірки. Цей об’єкт визначає правила валідації, такі як певний шаблон та мінімальна довжина.

Включіть наступний код як проп до компонента `StyledTextField` імені користувача.

 {...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'
    },
})}

Тепер, додайте наступний об’єкт як проп до компонента `StyledTextField` пароля.

 {...register('password', {
    required: 'Password required',
    minLength: {
        value: 8,
        message: 'Password must be at least 8 characters'
    },
})}

Додайте наступний код під полем вводу імені користувача, щоб забезпечити візуальний зворотній зв’язок щодо вимог до вводу.

Цей код відобразить сповіщення з повідомленням про помилку, щоб повідомити користувача про вимоги до вводу, гарантуючи, що він виправить будь-які помилки перед відправкою форми.

 {errors.username && <Alert severity="error">{errors.username.message}</Alert>} 

Нарешті, додайте подібний код відразу під полем вводу пароля:

 {errors.password && <Alert severity="error">{errors.password.message}</Alert>}

Чудово! З цими змінами ви отримали візуально привабливу та функціональну форму, створену за допомогою React Hook Form та Material UI.

Покращення розробки Next.js за допомогою клієнтських бібліотек

Material UI та React Hook Form – це лише два приклади чудових клієнтських бібліотек, які можна використовувати для прискорення розробки інтерфейсу Next.js.

Клієнтські бібліотеки пропонують різноманітні готові до використання функціональні можливості та компоненти, що можуть допомогти вам створювати кращі веб-додатки швидше та ефективніше.