9.0 KiB
9.0 KiB
Developer Quick Reference Guide
Common Patterns
1. Adding Notifications to a Component
import { useNotification } from '../contexts/NotificationContext';
function MyComponent() {
const notification = useNotification();
const handleAction = async () => {
try {
await performAction();
notification.showSuccess('Aktion erfolgreich durchgeführt');
} catch (error) {
notification.showError('Aktion fehlgeschlagen');
}
};
}
2. Implementing Loading States
import { useState, useEffect } from 'react';
import SkeletonCard from '../components/shared/SkeletonCard';
import { Fade } from '@mui/material';
function MyComponent() {
const [loading, setLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
fetchData().then(data => {
setData(data);
setLoading(false);
});
}, []);
if (loading) {
return <SkeletonCard variant="basic" />;
}
return (
<Fade in={true} timeout={600}>
<div>{/* Your content */}</div>
</Fade>
);
}
3. Displaying Empty States
import EmptyState from '../components/shared/EmptyState';
import { FolderOpen } from '@mui/icons-material';
function DataList({ items }) {
if (items.length === 0) {
return (
<EmptyState
icon={<FolderOpen />}
title="Keine Daten vorhanden"
message="Es wurden noch keine Einträge erstellt."
action={{
label: 'Neuen Eintrag erstellen',
onClick: () => navigate('/create')
}}
/>
);
}
return <div>{/* Render items */}</div>;
}
4. API Calls with Error Handling
import { api } from '../services/api';
import { useNotification } from '../contexts/NotificationContext';
function MyComponent() {
const notification = useNotification();
const fetchData = async () => {
try {
const response = await api.get('/endpoint');
return response.data;
} catch (error: any) {
notification.showError(
error.message || 'Fehler beim Laden der Daten'
);
throw error;
}
};
}
5. Protected Route Pattern
import ProtectedRoute from '../components/auth/ProtectedRoute';
// In App.tsx or routing configuration
<Route
path="/protected"
element={
<ProtectedRoute>
<MyProtectedComponent />
</ProtectedRoute>
}
/>
6. Accessing Auth Context
import { useAuth } from '../contexts/AuthContext';
function MyComponent() {
const { user, isAuthenticated, logout } = useAuth();
if (!isAuthenticated) {
return null;
}
return (
<div>
<p>Willkommen, {user?.name}</p>
<button onClick={logout}>Abmelden</button>
</div>
);
}
7. Using Custom Theme
import { useTheme } from '@mui/material';
function MyComponent() {
const theme = useTheme();
return (
<Box
sx={{
backgroundColor: theme.palette.primary.main,
color: theme.palette.primary.contrastText,
padding: theme.spacing(2),
borderRadius: theme.shape.borderRadius,
}}
>
Content
</Box>
);
}
8. Accessibility Best Practices
// Always add ARIA labels
<IconButton
aria-label="Menü öffnen"
onClick={handleOpen}
>
<MenuIcon />
</IconButton>
// Use Tooltips for icon-only buttons
<Tooltip title="Einstellungen öffnen">
<IconButton aria-label="Einstellungen öffnen">
<SettingsIcon />
</IconButton>
</Tooltip>
// Proper form labels
<TextField
label="E-Mail-Adresse"
type="email"
required
aria-required="true"
helperText="Bitte geben Sie eine gültige E-Mail-Adresse ein"
/>
9. Responsive Design Pattern
import { Box, useMediaQuery, useTheme } from '@mui/material';
function MyComponent() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
return (
<Box
sx={{
padding: isMobile ? 2 : 4,
flexDirection: isMobile ? 'column' : 'row',
}}
>
{/* Content */}
</Box>
);
}
10. Staggered Animations
import { Fade } from '@mui/material';
function ItemList({ items }) {
return (
<>
{items.map((item, index) => (
<Fade
key={item.id}
in={true}
timeout={600}
style={{ transitionDelay: `${index * 100}ms` }}
>
<div>{item.name}</div>
</Fade>
))}
</>
);
}
Common Components
SkeletonCard Variants
// Basic skeleton - simple text lines
<SkeletonCard variant="basic" />
// With avatar - includes circular avatar
<SkeletonCard variant="withAvatar" />
// Detailed - complex content with image
<SkeletonCard variant="detailed" />
Notification Severity Levels
const notification = useNotification();
// Success (green)
notification.showSuccess('Erfolgreich gespeichert');
// Error (red)
notification.showError('Fehler beim Speichern');
// Warning (orange)
notification.showWarning('Bitte überprüfen Sie Ihre Eingabe');
// Info (blue)
notification.showInfo('Dies ist eine Information');
Styling Patterns
Using Theme Colors
// Primary color
sx={{ color: 'primary.main' }}
sx={{ bgcolor: 'primary.light' }}
// Error/Success/Warning/Info
sx={{ color: 'error.main' }}
sx={{ bgcolor: 'success.light' }}
// Text colors
sx={{ color: 'text.primary' }}
sx={{ color: 'text.secondary' }}
// Background
sx={{ bgcolor: 'background.default' }}
sx={{ bgcolor: 'background.paper' }}
Spacing
// Using theme spacing (8px base)
sx={{
p: 2, // padding: 16px
mt: 3, // margin-top: 24px
mb: 4, // margin-bottom: 32px
gap: 2, // gap: 16px
}}
Responsive Breakpoints
sx={{
fontSize: { xs: '1rem', sm: '1.25rem', md: '1.5rem' },
display: { xs: 'none', sm: 'block' },
width: { xs: '100%', sm: '50%', md: '33.33%' },
}}
Error Handling Checklist
- Wrap async operations in try-catch
- Show user-friendly error messages
- Log errors to console for debugging
- Handle network errors specifically
- Handle authentication errors (401)
- Handle permission errors (403)
- Provide recovery actions when possible
- Don't expose sensitive error details to users
Performance Tips
- Use React.memo for components that render often
- Use useMemo for expensive calculations
- Use useCallback for event handlers passed to children
- Implement proper loading states
- Use lazy loading for large components
- Optimize images (compress, use correct format)
- Keep bundle size small (check build warnings)
- Use skeleton loaders instead of spinners
Accessibility Checklist
- All images have alt text
- All form inputs have labels
- All buttons have descriptive text or ARIA labels
- Color is not the only means of conveying information
- Focus indicators are visible
- Keyboard navigation works throughout
- Headings are in logical order (h1, h2, h3...)
- ARIA labels on icon buttons
- Error messages are announced to screen readers
Common German Translations
- Success: "Erfolgreich"
- Error: "Fehler"
- Loading: "Wird geladen..."
- Save: "Speichern"
- Cancel: "Abbrechen"
- Delete: "Löschen"
- Edit: "Bearbeiten"
- Create: "Erstellen"
- Back: "Zurück"
- Settings: "Einstellungen"
- Profile: "Profil"
- Logout: "Abmelden"
- Login: "Anmelden"
- Welcome: "Willkommen"
- No data: "Keine Daten vorhanden"
- Try again: "Erneut versuchen"
Testing Commands
# Development server
npm run dev
# Build for production
npm run build
# Preview production build
npm run preview
# Run linter
npm run lint
File Naming Conventions
- Components: PascalCase (e.g.,
MyComponent.tsx) - Hooks: camelCase with 'use' prefix (e.g.,
useMyHook.ts) - Utilities: camelCase (e.g.,
myHelper.ts) - Types: PascalCase (e.g.,
MyType.ts) - Constants: UPPER_SNAKE_CASE in files named lowercase
Import Order
- React and React libraries
- Third-party libraries (Material-UI, etc.)
- Internal contexts
- Internal components
- Internal utilities
- Types
- Styles
Example:
import { useState, useEffect } from 'react';
import { Box, Typography } from '@mui/material';
import { useAuth } from '../contexts/AuthContext';
import { useNotification } from '../contexts/NotificationContext';
import MyComponent from '../components/MyComponent';
import { formatDate } from '../utils/dateHelpers';
import { User } from '../types/auth.types';
Useful VS Code Snippets
Add to your .vscode/snippets.code-snippets:
{
"React Component": {
"prefix": "rfc",
"body": [
"import React from 'react';",
"",
"interface ${1:ComponentName}Props {",
" $2",
"}",
"",
"const ${1:ComponentName}: React.FC<${1:ComponentName}Props> = ($3) => {",
" return (",
" <div>",
" $4",
" </div>",
" );",
"};",
"",
"export default ${1:ComponentName};"
]
}
}