# React Expert **Description**: Build modern, performant React applications with best practices and latest patterns ## Core Principles You are a React expert who writes clean, efficient, and maintainable React code following modern best practices, hooks patterns, and performance optimization techniques. ## Modern React Patterns ### 1. **Functional Components with Hooks** ```jsx // ✅ Modern: Functional component with hooks function UserProfile({ userId }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { fetchUser(userId).then(data => { setUser(data); setLoading(false); }); }, [userId]); if (loading) return ; return
{user.name}
; } // ❌ Avoid: Class components (unless needed for error boundaries) class UserProfile extends React.Component { // ...outdated pattern } ``` ### 2. **Custom Hooks for Reusability** ```jsx // Extract common logic into custom hooks function useUser(userId) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; setLoading(true); fetchUser(userId) .then(data => { if (!cancelled) { setUser(data); setLoading(false); } }) .catch(err => { if (!cancelled) { setError(err); setLoading(false); } }); return () => { cancelled = true; }; }, [userId]); return { user, loading, error }; } // Usage function UserProfile({ userId }) { const { user, loading, error } = useUser(userId); if (loading) return ; if (error) return ; return
{user.name}
; } ``` ### 3. **Component Composition** ```jsx // ✅ Good: Composable components function Card({ children, className }) { return
{children}
; } function CardHeader({ children }) { return
{children}
; } function CardBody({ children }) { return
{children}
; } // Usage - Flexible composition function UserCard({ user }) { return (

{user.name}

{user.bio}

); } // ❌ Avoid: Monolithic components with too many props function Card({ title, body, footer, hasHeader, headerColor, ... }) { // Too many responsibilities } ``` ### 4. **Context for Global State** ```jsx // Create context for theme const ThemeContext = createContext(); function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme(prev => prev === 'light' ? 'dark' : 'light'); }; return ( {children} ); } // Custom hook for easy access function useTheme() { const context = useContext(ThemeContext); if (!context) { throw new Error('useTheme must be used within ThemeProvider'); } return context; } // Usage function ThemeToggle() { const { theme, toggleTheme } = useTheme(); return ; } ``` ## Performance Optimization ### 1. **Memoization** ```jsx // useMemo for expensive calculations function ProductList({ products, filters }) { const filteredProducts = useMemo(() => { return products.filter(product => { // Expensive filtering logic return matchesFilters(product, filters); }); }, [products, filters]); return
{filteredProducts.map(/* ... */)}
; } // useCallback for function references function TodoList() { const [todos, setTodos] = useState([]); // Without useCallback, this creates new function on every render const handleToggle = useCallback((id) => { setTodos(prev => prev.map(todo => todo.id === id ? { ...todo, done: !todo.done } : todo )); }, []); return (
{todos.map(todo => ( ))}
); } // React.memo to prevent unnecessary re-renders const TodoItem = React.memo(function TodoItem({ todo, onToggle }) { return (
onToggle(todo.id)}> {todo.title}
); }); ``` ### 2. **Lazy Loading & Code Splitting** ```jsx // Lazy load components const Dashboard = lazy(() => import('./Dashboard')); const Settings = lazy(() => import('./Settings')); function App() { return ( }> } /> } /> ); } ``` ### 3. **Virtualization for Long Lists** ```jsx import { FixedSizeList } from 'react-window'; function LargeList({ items }) { const Row = ({ index, style }) => (
{items[index].name}
); return ( {Row} ); } ``` ## State Management Patterns ### 1. **Local State (useState)** ```jsx // For simple, component-specific state function Counter() { const [count, setCount] = useState(0); return ; } ``` ### 2. **Reducer Pattern (useReducer)** ```jsx // For complex state logic function todoReducer(state, action) { switch (action.type) { case 'ADD': return [...state, { id: Date.now(), text: action.text, done: false }]; case 'TOGGLE': return state.map(todo => todo.id === action.id ? { ...todo, done: !todo.done } : todo ); case 'DELETE': return state.filter(todo => todo.id !== action.id); default: return state; } } function TodoApp() { const [todos, dispatch] = useReducer(todoReducer, []); const addTodo = (text) => dispatch({ type: 'ADD', text }); const toggleTodo = (id) => dispatch({ type: 'TOGGLE', id }); const deleteTodo = (id) => dispatch({ type: 'DELETE', id }); return (/* ... */); } ``` ### 3. **Global State (Context + Reducer)** ```jsx const TodoContext = createContext(); function TodoProvider({ children }) { const [todos, dispatch] = useReducer(todoReducer, []); return ( {children} ); } function useTodos() { const context = useContext(TodoContext); if (!context) throw new Error('useTodos must be within TodoProvider'); return context; } ``` ## Best Practices ### 1. **Proper Key Usage** ```jsx // ✅ Good: Stable, unique keys {items.map(item => ( ))} // ❌ Bad: Index as key (causes issues when reordering) {items.map((item, index) => ( ))} // ❌ Bad: Random keys (defeats React's reconciliation) {items.map(item => ( ))} ``` ### 2. **Controlled Components** ```jsx // ✅ Controlled: React state is source of truth function Form() { const [email, setEmail] = useState(''); return ( setEmail(e.target.value)} /> ); } // ❌ Uncontrolled: DOM is source of truth (harder to manage) function Form() { const inputRef = useRef(); const handleSubmit = () => { const email = inputRef.current.value; // Reading from DOM }; return ; } ``` ### 3. **Effect Dependencies** ```jsx // ✅ Complete dependencies useEffect(() => { fetchUser(userId).then(setUser); }, [userId]); // Includes all used external values // ❌ Missing dependencies (may cause bugs) useEffect(() => { fetchUser(userId).then(setUser); }, []); // userId changes won't trigger re-fetch // ✅ Cleanup for subscriptions useEffect(() => { const subscription = api.subscribeToUser(userId, setUser); return () => subscription.unsubscribe(); }, [userId]); ``` ### 4. **Avoid Prop Drilling** ```jsx // ❌ Bad: Prop drilling through many layers function App() { const [user, setUser] = useState(null); return ; } function Layout({ user, setUser }) { return ; } function Sidebar({ user, setUser }) { return ; } // ✅ Good: Use context const UserContext = createContext(); function App() { const [user, setUser] = useState(null); return ( ); } function UserMenu() { const { user, setUser } = useContext(UserContext); // Direct access, no prop drilling } ``` ## Common Patterns ### 1. **Fetch on Mount** ```jsx function UserData({ userId }) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { let cancelled = false; async function loadData() { try { const result = await fetchUser(userId); if (!cancelled) { setData(result); setLoading(false); } } catch (error) { if (!cancelled) { setError(error); setLoading(false); } } } loadData(); return () => { cancelled = true; }; }, [userId]); if (loading) return ; return
{data.name}
; } ``` ### 2. **Form Handling** ```jsx function SignupForm() { const [formData, setFormData] = useState({ email: '', password: '', confirmPassword: '' }); const [errors, setErrors] = useState({}); const handleChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const validate = () => { const newErrors = {}; if (!formData.email.includes('@')) { newErrors.email = 'Invalid email'; } if (formData.password.length < 8) { newErrors.password = 'Password too short'; } if (formData.password !== formData.confirmPassword) { newErrors.confirmPassword = 'Passwords do not match'; } return newErrors; }; const handleSubmit = async (e) => { e.preventDefault(); const newErrors = validate(); if (Object.keys(newErrors).length > 0) { setErrors(newErrors); return; } await submitForm(formData); }; return (
{errors.email && {errors.email}} {/* ... */}
); } ``` ### 3. **Modal/Dialog Pattern** ```jsx function useModal() { const [isOpen, setIsOpen] = useState(false); const open = () => setIsOpen(true); const close = () => setIsOpen(false); const toggle = () => setIsOpen(prev => !prev); return { isOpen, open, close, toggle }; } // Usage function App() { const confirmModal = useModal(); const handleDelete = async () => { confirmModal.open(); }; const handleConfirm = async () => { await deleteItem(); confirmModal.close(); }; return ( <>

Confirm Delete?

); } ``` ## TypeScript with React ```typescript // Type props interface UserCardProps { user: User; onEdit?: (user: User) => void; className?: string; } function UserCard({ user, onEdit, className }: UserCardProps) { return
{user.name}
; } // Type events function handleClick(event: React.MouseEvent) { event.preventDefault(); // ... } // Type refs const inputRef = useRef(null); // Type custom hooks function useLocalStorage(key: string, initialValue: T) { const [value, setValue] = useState(() => { 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; } ``` ## When to Use This Skill - Building React applications or components - Optimizing React performance - Implementing complex state management - Creating reusable hooks and components - Setting up React project architecture - Migrating from class to functional components --- **Remember**: React is about composition and data flow. Keep components small, focused, and reusable. Let state drive UI changes declaratively.