}) {
const files = use(filesPromise);
return files.map(f => );
}
// Usage with Suspense
}>
// ✅ React 19: use() for Context (conditional allowed)
function ConditionalTheme({ show }: { show: boolean }) {
if (show) {
const theme = use(ThemeContext);
return Themed
;
}
return null;
}
```
### useActionState for Forms
```typescript
// ✅ React 19: Form action with state
import { useActionState } from 'react';
function MergeForm() {
const [state, submitAction, isPending] = useActionState(
async (prev, formData) => {
const files = formData.getAll('files');
const result = await window.api.merge(files);
return result;
},
null
);
return (
);
}
```
### useOptimistic for Optimistic UI
```typescript
// ✅ React 19: Optimistic updates
import { useOptimistic } from 'react';
function FileList({ files }: { files: PdfFile[] }) {
const [optimisticFiles, addOptimistic] = useOptimistic(
files,
(state, newFile: PdfFile) => [...state, { ...newFile, pending: true }]
);
async function handleAdd(file: File) {
const tempFile = { id: 'temp', name: file.name, pending: true };
addOptimistic(tempFile);
await window.api.addFile(file);
}
return (
{optimisticFiles.map(f => (
))}
);
}
```
### ref Callback Cleanup
```typescript
// ✅ React 19: ref cleanup function
function AutoFocusInput() {
return (
{
if (el) el.focus();
return () => {
// cleanup when element removed
console.log('Input unmounted');
};
}}
/>
);
}
```
## Type Definition Rules
### No Inline Object Types
```typescript
// ❌ Avoid
function process(data: { id: string; name: string }) {}
// ✅ Preferred
interface ProcessData { id: string; name: string }
function process(data: ProcessData) {}
```
### Constants with ValueOf Pattern
```typescript
// Define constants
export const MERGE_STATUS = {
IDLE: 'idle',
PENDING: 'pending',
COMPLETE: 'complete',
} as const;
// Create union type
type ValueOf = T[keyof T];
type MergeStatus = ValueOf;
// Usage
const status: MergeStatus = MERGE_STATUS.PENDING;
```
## Resources
### references/
- `fsd-layers.md` - Detailed FSD layer documentation
- `electron-patterns.md` - Electron-specific patterns
To delete unused example files in `scripts/` and `assets/` directories as this skill focuses on architectural guidance.