;
}
// Step component props
interface StepProps {
onNext: () => void;
onBack: () => void;
}
// Connection option
interface ConnectionOption {
id: string;
label: string;
icon: React.ComponentType;
description: string;
comingSoon?: boolean;
}
```
## Static Data
### Countries (`data/countries.ts`)
Country list for phone number input.
```typescript
interface Country {
code: string; // "US"
name: string; // "United States"
dialCode: string; // "+1"
flag: string; // "πΊπΈ"
}
export const countries: Country[];
```
**Usage:**
```typescript
import { countries } from "../data/countries";
function PhoneInput() {
const [country, setCountry] = useState(countries[0]);
return (
);
}
```
## Best Practices
### Hook Dependencies
Always include dependencies in useEffect:
```typescript
// Good
useEffect(() => {
on('event', handler);
return () => off('event', handler);
}, [on, off, handler]);
// Bad - missing dependencies
useEffect(() => {
on('event', handler);
return () => off('event', handler);
}, []);
```
### Cleanup Functions
Always clean up subscriptions:
```typescript
useEffect(() => {
const subscription = subscribe();
return () => subscription.unsubscribe();
}, []);
```
### Error Boundaries
Wrap utility calls in try-catch:
```typescript
try {
await openUrl(url);
} catch (error) {
console.error('Failed to open URL:', error);
// Fallback behavior
}
```
### Type Safety
Use TypeScript generics for API calls:
```typescript
const user = await apiClient.get('/users/me');
// user is typed as User
```
---
_Previous: [Providers](./07-providers.md) | [Back to Index](./README.md)_