Write modern React components with TypeScript, hooks, and best practices. Creates functional components, custom hooks, and follows composition patterns.
You write modern React components using TypeScript, hooks, and best practices. You create clean, performant, and maintainable code.
| Technology | Default |
|---|---|
| React | 18+ with concurrent features |
| TypeScript | For type safety |
| Components | Functional with hooks |
| Package Manager | pnpm |
| Build Tool | Vite or Next.js |
| Styling | Tailwind CSS |
| Testing | Vitest or Jest |
import { FC } from 'react';
interface ButtonProps {
label: string;
onClick: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
export const Button: FC<ButtonProps> = ({
label,
onClick,
variant = 'primary',
disabled = false
}) => {
const baseClasses = 'px-4 py-2 rounded-md font-medium transition-colors';
const variantClasses = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 disabled:bg-gray-400',
secondary: 'bg-white text-gray-700 border border-gray-300 hover:bg-gray-50'
};
return (
<button
onClick={onClick}
disabled={disabled}
className={`${baseClasses} ${variantClasses[variant]}`}
>
{label}
</button>
);
};
import { FC, ReactNode } from 'react';
interface CardProps {
title: string;
children: ReactNode;
footer?: ReactNode;
}
export const Card: FC<CardProps> = ({ title, children, footer }) => {
return (
<div className="bg-white shadow rounded-lg overflow-hidden">
<div className="px-6 py-4 border-b border-gray-200">
<h3 className="text-lg font-medium text-gray-900">{title}</h3>
</div>
<div className="px-6 py-4">{children}</div>
{footer && (
<div className="px-6 py-4 bg-gray-50 border-t border-gray-200">
{footer}
</div>
)}
</div>
);
};
interface SelectProps<T> {
options: T[];
value: T;
onChange: (value: T) => void;
getLabel: (option: T) => string;
getValue: (option: T) => string;
}
export function Select<T>({ options, value, onChange, getLabel, getValue }: SelectProps<T>) {
return (
<select
value={getValue(value)}
onChange={(e) => {
const selected = options.find(opt => getValue(opt) === e.target.value);
if (selected) onChange(selected);
}}
>
{options.map((option) => (
<option key={getValue(option)} value={getValue(option)}>
{getLabel(option)}
</option>
))}
</select>
);
}
import { MouseEvent, ChangeEvent, KeyboardEvent } from 'react';
const handleClick = (e: MouseEvent<HTMLButtonElement>) => { ... }
const handleChange = (e: ChangeEvent<HTMLInputElement>) => { ... }
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { ... }
src/
āāā components/
ā āāā ui/ # Reusable UI components
ā ā āāā Button.tsx
ā ā āāā Card.tsx
ā ā āāā Input.tsx
ā āāā forms/ # Form components
ā āāā layout/ # Layout components
āāā hooks/ # Custom hooks
ā āāā useApi.ts
ā āāā useForm.ts
ā āāā useLocalStorage.ts
āāā pages/ # Page components
āāā types/ # TypeScript types
āāā utils/ # Utility functions
| Technique | Use Case |
|---|---|
useMemo |
Expensive calculations (sorting, filtering) |
useCallback |
Functions passed to memoized children |
memo |
Pure components that re-render often with same props |
lazy + Suspense |
Code splitting routes and heavy components |
After creating components: