Пошук уроків, статей та іншого контенту
Реалізуйте обробник submit, скасування стандартної відправки та безпечне читання даних форми.
submitФорма надсилається не лише після натискання кнопки. Подія submit також виникає, коли користувач натискає Enter у полі форми.
У React обробник submit передають у властивість onSubmit елемента <form>:
<form onSubmit={handleSubmit}>
{/* поля форми */}
</form>Функція handleSubmit отримає об’єкт події. Через нього можна скасувати стандартну поведінку браузера та прочитати дані форми.
За замовчуванням браузер намагається відправити форму на адресу, вказану в action. Часто це призводить до перезавантаження сторінки.
У React стандартну поведінку скасовують методом event.preventDefault():
function handleSubmit(event) {
event.preventDefault();
// Тут можна обробити дані форми
}preventDefault() потрібно викликати на початку обробника, до роботи з даними форми.
Після цього React-компонент може самостійно:
перевірити введені значення;
показати повідомлення про помилку;
надіслати дані на сервер;
оновити стан компонента.
FormDataОб’єкт FormData дозволяє отримати значення всіх полів форми:
const formData = new FormData(event.currentTarget);Щоб поле потрапило до FormData, воно повинно мати атрибут name:
<input name="email" />Значення окремого поля можна отримати методом get:
const email = formData.get("email");Метод get може повернути:
рядок для текстового поля;
об’єкт File для поля завантаження файлів;
null, якщо поля з таким іменем немає.
Тому перед використанням значення варто перевірити його тип.
import { useState } from "react";
export default function RegistrationForm() {
const [message, setMessage] = useState("");
function handleSubmit(event) {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);
const usernameValue = formData.get("username");
const emailValue = formData.get("email");
// Перевіряємо, що значення є текстом
if (typeof usernameValue !== "string" || typeof emailValue !== "string") {
setMessage("Не вдалося прочитати дані форми.");
return;
}
const username = usernameValue.trim();
const email = emailValue.trim();
if (!username || !email) {
setMessage("Заповніть усі поля.");
return;
}
setMessage(`Форму надіслано для ${username} (${email})`);
form.reset();
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="username">Ім’я користувача</label>
<input id="username" name="username" type="text" />
</div>
<div>
<label htmlFor="email">Електронна пошта</label>
<input id="email" name="email" type="email" />
</div>
<button type="submit">Зареєструватися</button>
{message && <p>{message}</p>}
</form>
);
}У цьому прикладі:
onSubmit={handleSubmit} підключає обробник до форми.
event.preventDefault() не дає браузеру перезавантажити сторінку.
event.currentTarget посилається саме на форму, яка викликала обробник.
FormData збирає значення полів із name.
typeof перевіряє, що отримане значення можна обробляти як текст.
trim() прибирає зайві пробіли на початку та в кінці.
form.reset() очищає поля після успішної обробки.
currentTarget і targetВ обробнику події доступні дві схожі властивості:
event.currentTarget — елемент, на якому зареєстровано обробник;
event.target — елемент, який безпосередньо був джерелом події.
Для читання даних форми краще використовувати event.currentTarget:
function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
}Це надійно працює незалежно від того, чи користувач натиснув кнопку, чи надіслав форму клавішею Enter.
Не варто одразу викликати методи рядка на результаті formData.get():
const username = formData.get("username").trim();Якщо поле відсутнє, get() поверне null, і програма завершиться з помилкою.
Безпечніший варіант:
const value = formData.get("username");
if (typeof value !== "string") {
return;
}
const username = value.trim();Для звичайних текстових полів можна також використати значення за замовчуванням:
const username = String(formData.get("username") ?? "").trim();Однак явна перевірка через typeof краще показує, що програма враховує різні типи значень FormData.
nameПоля без name не будуть доступні через FormData:
<input id="email" type="email" />У цьому випадку:
formData.get("email"); // nullПравильний варіант:
<input id="email" name="email" type="email" />id потрібен, зокрема, для зв’язку з <label>, а name — для ідентифікації поля в даних форми.
Для кнопки, яка надсилає форму, потрібно використовувати:
<button type="submit">Надіслати</button>Кнопка з type="submit" запускає подію submit форми. Це краще, ніж окремо обробляти onClick, оскільки submit також працює під час натискання Enter.
onClick замість onSubmit<form>
<button onClick={handleSubmit}>Надіслати</button>
</form>Такий підхід не враховує надсилання форми клавішею Enter. Обробник потрібно призначати самій формі:
<form onSubmit={handleSubmit}>
<button type="submit">Надіслати</button>
</form>preventDefault()Без event.preventDefault() браузер може перезавантажити сторінку та стерти поточний стан компонента.
function handleSubmit(event) {
event.preventDefault();
// Подальша обробка
}name<input type="text" id="username" />Таке поле не можна отримати за допомогою formData.get("username"). Додайте name:
<input type="text" id="username" name="username" />const email = formData.get("email").trim();get() може повернути null, тому значення потрібно перевірити перед викликом trim() або іншого методу.
event.target для пошуку формиevent.target може бути кнопкою або іншим елементом, який став джерелом події. Для створення FormData використовуйте:
const formData = new FormData(event.currentTarget);Для обробки відправки форми в React використовуйте onSubmit.
Викликайте event.preventDefault(), щоб скасувати перезавантаження сторінки.
Для читання полів створюйте new FormData(event.currentTarget).
Кожне поле, яке потрібно прочитати, повинно мати атрибут name.
Результат formData.get() може бути null, тому його потрібно перевіряти.
Для кнопки відправки використовуйте type="submit".
Обробка submit працює і після натискання кнопки, і після натискання Enter.