)
}
```
**Offline-Aware Actions:**
For convenience, use the offline-aware action wrappers from `lib/offline-actions.ts`:
```typescript
import { createItemOffline, updateItemOffline, deleteItemOffline } from '@/lib/offline-actions'
// These automatically queue mutations when offline
await createItemOffline(listId, title, description, metadata)
await updateItemOffline(itemId, updates)
await deleteItemOffline(itemId)
```
## Requirements Validation
These hooks implement the following requirements from the specification:
- **Requirement 4.5**: Offline synchronization when connectivity restored
- **Requirement 6.4**: Filter state management and clearing
- **Requirement 7.3**: Visual feedback for user actions (optimistic updates)
- **Requirement 7.4**: Scroll position preservation
- **Requirement 8.3**: Search clearing and restoration
## Best Practices
1. **Search Debouncing**: Use appropriate debounce times (300ms is a good default)
2. **Filter State**: Keep filter state in sync with URL params for shareable links
3. **Optimistic Updates**: Always provide rollback on error
4. **Scroll Position**: Use unique keys for different views to avoid conflicts
5. **Error Handling**: Always handle errors in async callbacks
## Testing
These hooks are designed to be testable with React Testing Library:
```typescript
import { renderHook, act } from '@testing-library/react'
import { useSearch } from '@/hooks'
test('useSearch debounces queries', async () => {
const onSearch = jest.fn()
const { result } = renderHook(() => useSearch({ onSearch, debounceMs: 100 }))
act(() => {
result.current.setQuery('test')
})
expect(onSearch).not.toHaveBeenCalled()
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 150))
})
expect(onSearch).toHaveBeenCalledWith('test')
})
```