FluentStack

Reusable Form Field Pattern

Mode tersedia: dark, light, paper
MasukDaftar
Advanced · Level 9: React AdvancedAdvanced75 menitBahasa Indonesia

Reusable Form Field Pattern

Menyusun label, input, hint, dan error menjadi pola form field yang konsisten sekaligus mudah diakses.

StatusMemuat progres
ProgresMemuat...

...

Memuat progres

Menyiapkan langkah berikutnya

Tujuan belajar

  • Menjelaskan bagian accessibility yang perlu konsisten pada form field
  • Membuat FormField sebagai wrapper layout yang jelas
  • Menghubungkan input dengan label, hint, dan error yang relevan
ReactFormsAccessibilityCompositionComponent API

Isi lesson

5 blok
  1. 1.
    Pengulangan form biasanya membawa aturan yang samaBelum selesaiWajib
  2. 2.
    FormField menjaga hubungan label, hint, dan errorBelum selesaiWajib
  3. 3.
    Wrapper visual saja belum cukupBelum selesaiWajib
  4. 4.
    Coding practiceBelum selesaiWajib
  5. 5.
    RingkasanBelum selesaiWajib

Pengulangan form biasanya membawa aturan yang sama

Wajib

Form field sering mengulang struktur yang sama: label, control, hint, dan pesan error. Pengulangan ini bukan hanya soal spacing. Label harus menunjuk input yang tepat, hint dan error perlu memiliki id yang bisa dirujuk, dan error perlu muncul dengan cara yang dapat dipahami user.

FormField di module ini adalah layout wrapper kecil. Ia tidak mencoba menangani semua jenis input, validasi server, mask, atau library form. Input tetap dimasukkan lewat children sehingga component ini dapat dipakai untuk text input, textarea, atau select tanpa API generik yang sulit dibaca.

Bagian ini memengaruhi progres lesson.

FormField menjaga hubungan label, hint, dan error

Wajib
tsx
import { useState, type ReactNode } from "react";

type FormFieldProps = {
  id: string;
  label: string;
  hint?: string;
  error?: string;
  children: ReactNode;
};

function FormField({ id, label, hint, error, children }: FormFieldProps) {
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      {children}
      {hint ? <p id={id + "-hint"}>{hint}</p> : null}
      {error ? <p id={id + "-error"} role="alert">{error}</p> : null}
    </div>
  );
}

export function ProfileForm() {
  const [displayName, setDisplayName] = useState("Rina");
  const error = displayName.trim().length < 3 ? "Nama tampilan minimal 3 karakter." : "";
  const describedBy = error
    ? "display-name-hint display-name-error"
    : "display-name-hint";

  return (
    <form>
      <FormField
        id="display-name"
        label="Nama tampilan"
        hint="Nama ini terlihat pada profile kamu."
        error={error}
      >
        <input
          id="display-name"
          value={displayName}
          aria-describedby={describedBy}
          aria-invalid={Boolean(error)}
          onChange={(event) => setDisplayName(event.target.value)}
        />
      </FormField>
    </form>
  );
}

FormField membuat label dan pesan pendukung pada tempat yang konsisten. Input tetap dimiliki ProfileForm karena nilai, validasi, dan aria-describedby bergantung pada state form saat itu. Jangan membuat FormField mengambil alih seluruh state semua input hanya karena markup label berulang.

Bagian ini memengaruhi progres lesson.

Kesalahan umum

Wajib

Wrapper visual saja belum cukup

Jangan menyebut component sebagai FormField jika ia hanya menambah border lalu melupakan htmlFor, id, hint, atau error relationship. Reusability yang baik menjaga aturan yang mudah terlupa, bukan hanya memindahkan div ke file lain.

Bagian ini memengaruhi progres lesson.

Coding practice

WajibDibuka di workspace khusus

Build accessible profile form field

Buat FormField kecil yang menjaga label, hint, error, dan input profile tetap terhubung saat user mengubah nama tampilan.

Tujuan awal: Fokus di tab TSX.

Practice ini dibuka di workspace khusus. Buka practice untuk memakai editor, preview, dan cek otomatis.

Tombol selesai aktif setelah semua validasi wajib lolos.

9 cek otomatis5 checklist
Belum selesaiBuka practice

Ringkasan

Wajib
  • FormField dapat menyatukan markup label, hint, dan error yang berulang.
  • Input tetap menerima id, aria-describedby, dan aria-invalid sesuai state form saat ini.
  • Abstraction yang baik melindungi aturan accessibility yang mudah terlewat.
  • Berikutnya, kamu akan memilih kapan pola seperti ini membantu dan kapan component sederhana lebih baik dibiarkan lokal.

Bagian ini memengaruhi progres lesson.

Langkah berikutnya

Selesaikan bagian penting lesson ini

Lanjutkan blok wajib berikutnya: Pengulangan form biasanya membawa aturan yang sama.