react-core
React Core Best Practices
Comprehensive React development guidelines with Vercel optimization patterns.
Instructions
1. Component Structure
// ✅ Max 200 lines per component
// ✅ Single responsibility
interface Props {
user: User;
onUpdate: (user: User) => void;
}
export function UserCard({ user, onUpdate }: Props) {
// Hooks first
const [isEditing, setIsEditing] = useState(false);
// Derived state (no useState needed)
const fullName = `${user.firstName} ${user.lastName}`;
// Event handlers
const handleSubmit = () => { ... };
// Render
return (
<div className="user-card">
<h2>{fullName}</h2>
...
</div>
);
}
2. Derived State (No useState)
// ❌ Bad - unnecessary state
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);
// ✅ Good - derived state
const fullName = `${firstName} ${lastName}`;
// ✅ Good - expensive computation
const sortedItems = useMemo(
() => items.sort((a, b) => a.name.localeCompare(b.name)),
[items]
);
3. Functional setState
// ❌ Bad - stale state risk
setCount(count + 1);
// ✅ Good - always current
setCount(prev => prev + 1);
// ✅ Good - object state
setUser(prev => ({ ...prev, name: newName }));
4. Prevent Unnecessary Re-renders
// ✅ Primitive dependencies for useMemo
const result = useMemo(() => {
return expensiveCalculation(id);
}, [id]); // id is primitive
// ✅ Stable callback references
const handleClick = useCallback(() => {
doSomething(id);
}, [id]);
// ✅ Memoize child components
const MemoizedChild = memo(ChildComponent);
5. Event Handlers
// ❌ Bad - creates new function each render
<button onClick={() => handleClick(item.id)}>
// ✅ Good - stable reference with data attribute
<button data-id={item.id} onClick={handleClick}>
function handleClick(e: React.MouseEvent<HTMLButtonElement>) {
const id = e.currentTarget.dataset.id;
// ...
}
6. Custom Hooks
// ✅ Extract reusable logic
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}
7. Props Pattern
// ✅ Destructure props
function Button({ children, variant = 'primary', ...rest }: ButtonProps) {
return (
<button className={`btn-${variant}`} {...rest}>
{children}
</button>
);
}
8. Loading & Error States
function UserProfile({ userId }: Props) {
const { data, isLoading, error } = useUser(userId);
if (isLoading) return <Skeleton />;
if (error) return <ErrorMessage error={error} />;
if (!data) return <NotFound />;
return <UserCard user={data} />;
}
References
More from alicoder001/agent-skills
typescript
TypeScript strict mode patterns, naming conventions, and type safety rules. Use when writing TypeScript code, defining types, or reviewing TypeScript projects. Includes generics, utility types, and best practices.
35security
Security best practices for web applications. Use when handling user input, authentication, or sensitive data. Covers XSS, SQL injection, CSRF, environment variables, and secure coding patterns.
22memory
Working memory management, context prioritization, and knowledge retention patterns for AI agents. Use when you need to maintain relevant context and avoid information loss during long tasks.
22react-vite
React + Vite SPA development patterns including project setup, configuration, and optimization. Use for building single-page applications with Vite bundler.
22react-nextjs
Next.js 14+ App Router best practices including Server Components, data fetching, caching, and Vercel optimization patterns. Use for Next.js development with waterfall prevention, bundle optimization, and server actions.
17nestjs
NestJS modular architecture patterns including modules, services, controllers, DTOs, and database integration. Use for building scalable Node.js backend applications with Prisma ORM.
16