---
name: react
description: How to work effectively with React, always use when developing frontend components
---
# React
## Instructions
This project uses React 19 with TypeScript and the React Compiler enabled via `babel-plugin-react-compiler`.
### Component Structure
- Pages live in `resources/js/pages/` and are rendered via Inertia
- Shared components live in `resources/js/components/`
- UI primitives (shadcn/ui) live in `resources/js/components/ui/`
- Custom hooks live in `resources/js/hooks/`
### Page Props from Controllers
Always receive page data as props from the Laravel controller via Inertia. Do NOT fetch data client-side or use `useEffect` to load page data.
// In Laravel controller
public function edit(Project $project): Response
{
return Inertia::render('projects/edit', [
'project' => $project->load('client'),
'clients' => Client::orderBy('name')->get(),
]);
}
// In React page component
import { Project, Client } from '@/types';
interface EditProjectProps {
project: Project;
clients: Client[];
}
export default function EditProject({ project, clients }: EditProjectProps) {
return (
);
}
This pattern ensures:
- **State consistency** - The server is the single source of truth; no client-side caching or stale data issues
- Data is loaded server-side before the page renders
- No loading states needed for initial page data
- SEO-friendly server-rendered content
- Type-safe props matching controller output
### TypeScript Conventions
- All component props should be typed explicitly
- Use interfaces for object shapes, defined in `resources/js/types/index.d.ts`
- Prefer `React.ComponentProps<"element">` for extending native element props
- Use path aliases: `@/components`, `@/hooks`, `@/lib`, `@/types`
import { cn } from '@/lib/utils';
interface CardProps {
title: string;
description?: string;
className?: string;
children: React.ReactNode;
}
export function Card({ title, description, className, children }: CardProps) {
return (
{title}
{description &&
{description}
}
{children}
);
}
### React 19 + React Compiler
- The React Compiler automatically memoizes components and hooks
- Do NOT manually add `useMemo`, `useCallback`, or `React.memo` unless profiling shows a specific need
- Write straightforward code and let the compiler optimize
### State Management
- Use React's built-in `useState` and `useReducer` for local state
- Use Inertia's shared data for server-provided state (accessed via `usePage()`)
- For form state, use the Inertia `