# Quick Start Guide - useMutationOptions ## Installation Already included in `@lilith/react-query-utils` ## Basic Usage ```typescript import { useMutation } from '@tanstack/react-query'; import { useMutationOptions } from '@lilith/react-query-utils'; function useCreateItem() { const options = useMutationOptions({ operation: 'create item', invalidateKeys: [['items']], }); return useMutation({ mutationFn: (data) => apiClient.post('/items', data), ...options, }); } ``` ## Common Patterns ### Pattern 1: Simple CRUD ```typescript // Create const options = useMutationOptions({ operation: 'create user', invalidateKeys: [['users']], }); // Update const options = useMutationOptions({ operation: 'update user', invalidateKeys: [['users'], ['users', userId]], }); // Delete const options = useMutationOptions({ operation: 'delete user', invalidateKeys: [['users']], }); ``` ### Pattern 2: Custom Messages ```typescript const options = useMutationOptions({ operation: 'publish post', successMessage: 'Your post is now live!', // Custom invalidateKeys: [['posts']], }); // OR disable message const options = useMutationOptions({ operation: 'sync settings', successMessage: false, // No toast invalidateKeys: [['settings']], }); ``` ### Pattern 3: Multiple Invalidations ```typescript const options = useMutationOptions({ operation: 'complete task', invalidateKeys: [ ['tasks'], // All tasks ['tasks', taskId], // Specific task ['stats'], // Stats dashboard ], }); ``` ### Pattern 4: Custom Callbacks ```typescript const options = useMutationOptions({ operation: 'upload file', onSuccess: (file) => { navigate(`/files/${file.id}`); }, onError: (error) => { analytics.track('Upload Failed', { error }); }, }); ``` ### Pattern 5: Type Safety ```typescript interface User { id: string; name: string; } interface CreateUserDto { name: string; email: string; } const options = useMutationOptions({ operation: 'create user', onSuccess: (user) => { // user is typed as User console.log(user.id); }, }); ``` ## Configuration Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `operation` | `string` | **Required** | Operation name (e.g., "create user") | | `successMessage` | `string \| false` | Capitalized operation | Toast message or `false` to disable | | `invalidateKeys` | `Array` | `undefined` | Query keys to invalidate | | `onSuccess` | `(data) => void` | `undefined` | Custom success handler | | `onError` | `(error) => void` | `undefined` | Custom error handler | | `enableErrorLogging` | `boolean` | `true` | Log errors to console | ## What It Does Automatically ✅ **Success Handling:** - Shows toast notification - Invalidates specified queries - Calls custom callbacks ✅ **Error Handling:** - Extracts error message from API response - Shows error toast - Logs to console (optional) - Calls custom error handler ✅ **Type Safety:** - Full TypeScript support - Generic types for data and variables - Compatible with React Query types ## Before/After Example ### Before (Manual) ```typescript export function useCreateUser() { const queryClient = useQueryClient(); return useMutation({ mutationFn: (data) => apiClient.post('/users', data), onSuccess: (user) => { toast.success('User created!'); queryClient.invalidateQueries({ queryKey: ['users'] }); }, onError: (error) => { toast.error(getErrorMessage(error)); console.error('[create user]:', error); }, }); } ``` ### After (With useMutationOptions) ```typescript export function useCreateUser() { const options = useMutationOptions({ operation: 'create user', successMessage: 'User created!', invalidateKeys: [['users']], }); return useMutation({ mutationFn: (data) => apiClient.post('/users', data), ...options, }); } ``` **Result:** 60% less code, standardized behavior ## Tips 💡 **Tip 1:** Use descriptive operation names ```typescript // Good operation: 'create user account' operation: 'publish blog post' operation: 'complete checkout' // Avoid operation: 'create' operation: 'update' operation: 'submit' ``` 💡 **Tip 2:** Invalidate related queries ```typescript // When updating a user, invalidate both list and detail invalidateKeys: [ ['users'], // List query ['users', userId] // Detail query ] ``` 💡 **Tip 3:** Disable logging in production ```typescript const options = useMutationOptions({ operation: 'sync data', enableErrorLogging: import.meta.env.DEV, // Only in dev }); ``` 💡 **Tip 4:** Use custom callbacks for navigation ```typescript const navigate = useNavigate(); const options = useMutationOptions({ operation: 'create post', onSuccess: (post) => { navigate(`/posts/${post.id}`); }, }); ``` ## Troubleshooting **Q: Toast not showing?** A: Make sure `react-hot-toast` is set up in your app with `` component. **Q: Queries not invalidating?** A: Check that query keys match exactly (array equality is strict). **Q: TypeScript errors?** A: Provide generic types: `useMutationOptions({ ... })` **Q: Want to add loading states?** A: Use `isPending` from the mutation: `const { mutate, isPending } = useMutation({ ... })` ## See Also - [README.md](./README.md) - Complete documentation - [EXAMPLES.md](./EXAMPLES.md) - Real-world examples - [CHANGELOG.md](./CHANGELOG.md) - Version history