# React Patterns and Best Practices
## Component Structure
### Functional Components
Always prefer functional components with hooks over class components:
```jsx
// ✅ Good
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUser(userId).then(setUser).finally(() => setLoading(false));
}, [userId]);
if (loading) return ;
if (!user) return ;
return ;
}
// ❌ Avoid class components for new code
class UserProfile extends Component { ... }
```
### Component Organization
```
ComponentName/
├── index.js // Export only
├── ComponentName.jsx // Main component
├── hooks.js // Custom hooks
├── styles.module.css // Component styles
└── __tests__/ // Tests
└── ComponentName.test.jsx
```
## State Management
### Local State with useState
```jsx
// ✅ Good - Separate concerns
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// ❌ Avoid - Single object state
const [state, setState] = useState({ user: null, loading: false, error: null });
```
### Complex State with useReducer
```jsx
const initialState = { user: null, loading: false, error: null };
function userReducer(state, action) {
switch (action.type) {
case 'FETCH_START':
return { ...state, loading: true, error: null };
case 'FETCH_SUCCESS':
return { ...state, loading: false, user: action.payload };
case 'FETCH_ERROR':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
}
```
## Custom Hooks
Extract reusable logic into custom hooks:
```jsx
function useUser(userId) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
if (!userId) return;
fetchUser(userId)
.then(setUser)
.catch(setError)
.finally(() => setLoading(false));
}, [userId]);
return { user, loading, error };
}
// Usage
function UserProfile({ userId }) {
const { user, loading, error } = useUser(userId);
// ... render logic
}
```
## Performance Optimization
### Memoization
```jsx
// Memoize expensive calculations
const expensiveValue = useMemo(() => {
return heavyCalculation(data);
}, [data]);
// Memoize components
const MemoizedComponent = React.memo(({ data }) => {
return ;
});
// Memoize callbacks
const handleClick = useCallback(() => {
onItemClick(item.id);
}, [item.id, onItemClick]);
```
### Code Splitting
```jsx
// Lazy load components
const LazyComponent = lazy(() => import('./LazyComponent'));
function App() {
return (
}>
);
}
```
## Error Boundaries
```jsx
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return ;
}
return this.props.children;
}
}
```
## Accessibility
- Use semantic HTML elements
- Provide alt text for images
- Include proper ARIA labels
- Ensure keyboard navigation works
- Test with screen readers
```jsx
// ✅ Good
// ❌ Avoid
Submit
```