Use Cases (Diperbarui: 2/6/2026)

React dengan Claude Code untuk produksi: komponen, Hooks, test, dan review

Gunakan Claude Code untuk React yang aman: komponen typed, Hooks, test, aksesibilitas, performa, dan review.

React dengan Claude Code untuk produksi: komponen, Hooks, test, dan review

Claude Code bisa mempercepat development React, tetapi tim produksi tidak hanya butuh cepat. Tim butuh perubahan kecil, mudah direview, dan bisa dibuktikan lewat test. Jika prompt terlalu umum seperti “buat dashboard yang bagus”, hasilnya sering berupa terlalu banyak komponen, terlalu banyak props, dan sedikit bukti kualitas.

Panduan ini membahas workflow React + TypeScript: batas komponen, props, state, custom hook, form, data fetching, Testing Library, aksesibilitas, performa, dan prompt review. Jadikan sumber resmi sebagai baseline: React docs, React Testing Library, MDN ARIA, dan Claude Code docs. Untuk konteks lokal ClaudeCodeLab, lanjutkan ke TypeScript tips, strategi testing, aksesibilitas, dan optimasi performa.

Mulai dari kontrak

Props adalah input dari parent ke child. State adalah nilai yang diingat UI. Custom hook adalah fungsi reusable untuk logic state dan side effect. Side effect mencakup API call, timer, dan localStorage.

InformasiContohManfaat
Tanggung jawab UIdaftar user, filter role, toggle activemencegah komponen terlalu besar
Lokasi stateparent, URL, hook, server cachemencegah useState tersebar
Bentuk datatipe User, API response, empty stateprops dan test lebih jelas
Verifikasinpm test, npm run build, keyboardada bukti untuk review

Use case nyata

Pertama, internal admin list: user, invoice, ticket, role, atau product. Claude Code bisa memisahkan filter, table, row action, empty state, dan error state tanpa mengubah kontrak API.

Kedua, form untuk profile edit, contact, checkout, atau signup training. Prompt harus menyebut label, validasi, status submitting, dan retry. Untuk form yang lebih besar, baca React Hook Form dengan Claude Code.

Ketiga, layar data fetching seperti search results, notifications, dan dashboard. Server state jangan dicampur dengan UI state sementara. Untuk TanStack Query, lihat TanStack Query; untuk client state kecil, lihat Zustand.

Keempat, review diff. Minta Claude Code memeriksa batas komponen, Effect yang tidak perlu, label yang hilang, test rapuh, dan re-render yang bisa dihindari.

Diagram komponen

UserAdminPage
  -> UserFilters: search dan role filter
  -> UserTable: table dan actions
  -> UserStatusBadge: hanya status display
  -> UserEditDialog: form edit
  -> useUsers: fetch, refresh, error

Jika props sebuah komponen tidak bisa dijelaskan dalam satu kalimat, kemungkinan komponen itu melakukan terlalu banyak hal. Jika komponen hanya dipakai sekali dan tidak punya behavior, extraction mungkin terlalu cepat.

Komponen React typed

import type { FormEvent } from "react";

export type UserRole = "admin" | "editor" | "viewer";

export type User = {
  id: string;
  name: string;
  email: string;
  role: UserRole;
  active: boolean;
};

type UserTableProps = {
  users: User[];
  selectedRole: "all" | UserRole;
  onRoleChange: (role: "all" | UserRole) => void;
  onToggleActive: (id: string) => void;
};

export function UserTable({ users, selectedRole, onRoleChange, onToggleActive }: UserTableProps) {
  const filteredUsers = selectedRole === "all" ? users : users.filter((user) => user.role === selectedRole);

  function handleRoleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    onRoleChange(formData.get("role") as "all" | UserRole);
  }

  return (
    <section aria-labelledby="user-table-title">
      <h2 id="user-table-title">Team members</h2>
      <form onSubmit={handleRoleSubmit} style={{ marginBottom: 12 }}>
        <label htmlFor="role">Filter by role </label>
        <select id="role" name="role" defaultValue={selectedRole}>
          <option value="all">All</option>
          <option value="admin">Admin</option>
          <option value="editor">Editor</option>
          <option value="viewer">Viewer</option>
        </select>
        <button type="submit">Apply</button>
      </form>
      {filteredUsers.length === 0 ? (
        <p role="status">No users match this filter.</p>
      ) : (
        <table>
          <thead>
            <tr>
              <th scope="col">Name</th>
              <th scope="col">Email</th>
              <th scope="col">Role</th>
              <th scope="col">Status</th>
              <th scope="col">Action</th>
            </tr>
          </thead>
          <tbody>
            {filteredUsers.map((user) => (
              <tr key={user.id}>
                <td>{user.name}</td>
                <td>{user.email}</td>
                <td>{user.role}</td>
                <td>{user.active ? "Active" : "Paused"}</td>
                <td>
                  <button type="button" onClick={() => onToggleActive(user.id)}>
                    {user.active ? "Pause" : "Activate"}
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      )}
    </section>
  );
}

Hook dan test

import { useEffect, useState } from "react";
import type { User } from "./UserTable";

type UsersState =
  | { status: "loading"; users: User[]; error: null }
  | { status: "success"; users: User[]; error: null }
  | { status: "error"; users: User[]; error: string };

export function useUsers(endpoint: string) {
  const [state, setState] = useState<UsersState>({ status: "loading", users: [], error: null });

  useEffect(() => {
    const controller = new AbortController();
    async function loadUsers() {
      setState({ status: "loading", users: [], error: null });
      try {
        const response = await fetch(endpoint, { signal: controller.signal });
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const users = (await response.json()) as User[];
        setState({ status: "success", users, error: null });
      } catch (error) {
        if (error instanceof DOMException && error.name === "AbortError") return;
        setState({ status: "error", users: [], error: error instanceof Error ? error.message : "Unknown error" });
      }
    }
    void loadUsers();
    return () => controller.abort();
  }, [endpoint]);

  return state;
}
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import { UserTable, type User } from "./UserTable";

const users: User[] = [
  { id: "1", name: "Masa", email: "masa@example.com", role: "admin", active: true },
  { id: "2", name: "Aiko", email: "aiko@example.com", role: "viewer", active: false },
];

describe("UserTable", () => {
  it("filters users and toggles active status", async () => {
    const user = userEvent.setup();
    const onRoleChange = vi.fn();
    const onToggleActive = vi.fn();
    render(<UserTable users={users} selectedRole="all" onRoleChange={onRoleChange} onToggleActive={onToggleActive} />);
    await user.selectOptions(screen.getByLabelText(/filter by role/i), "viewer");
    await user.click(screen.getByRole("button", { name: /apply/i }));
    await user.click(screen.getByRole("button", { name: /activate/i }));
    expect(onRoleChange).toHaveBeenCalledWith("viewer");
    expect(onToggleActive).toHaveBeenCalledWith("2");
  });
});

Prompt review

Review diff React + TypeScript ini.
Periksa batas komponen, props yang berlebihan, useEffect yang tidak perlu, campuran UI state dan server state, label dan error form, coverage Testing Library, serta risiko re-render pada list besar.
Jangan tambah library baru. Akhiri dengan checklist npm test dan npm run build.

Pitfall umum

Pitfall yang sering muncul: komponen terlalu banyak, useEffect untuk nilai turunan, input tanpa label, icon button tanpa accessible name, error hanya dengan warna, dan optimasi performa tanpa pengukuran. Prompt yang baik meminta abstraksi paling kecil yang berguna, test dari sudut pandang user, dan cek aksesibilitas.

CTA dan hasil

Untuk tim, tulis aturan ini di CLAUDE.md: batas komponen, command test, aksesibilitas, dan batas over-abstraction. Training dan konsultasi Claude Code dari ClaudeCodeLab bisa membantu menerapkan workflow ini di repo React nyata, termasuk UI review, Testing Library, performance proof, dan CTA untuk konsultasi atau penjualan.

Hasil praktik: saat Masa memakai alur ini untuk UI admin situs konten, cleanup props dan revisi aksesibilitas berkurang karena boundary, ownership state, dan ekspektasi test sudah diberikan sebelum code generation. Pola yang paling stabil adalah diff kecil yang bisa diverifikasi.

#Claude Code #React #frontend #components #Hooks
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.