| name | custom-hook |
| description | Creates custom React hooks for SideDish. Use when the user asks to create a new hook, extract shared logic into a hook, or refactor component logic into reusable hooks. Includes TypeScript interfaces, memoization patterns, and index.ts export. |
| allowed-tools | ["Read","Write","Edit","Glob","Grep"] |
Custom Hook Skill
When to Use
- Creating a new reusable hook (e.g., "create a hook for X")
- Extracting repeated logic from components
- Building hooks for form state, API calls, or UI interactions
Quick Start
1. File Location & Naming
src/hooks/useHookName.ts # 파일명: use + PascalCase
2. Required Structure
import { useState, useCallback } from 'react'
import { toast } from 'sonner'
export interface UseHookNameOptions {
initialValue?: string
onError?: (error: string) => void
onChange?: (value: string) => void
}
export interface UseHookNameReturn {
value: string
setValue: (value: string) => void
reset: () => void
isValid: boolean
}
export function useHookName(options: UseHookNameOptions = {}): UseHookNameReturn {
const { initialValue = '', onError, onChange } = options
const [value, setValueInternal] = useState(initialValue)
const handleError = useCallback((message: string) => {
onError ? onError(message) : toast.error(message)
}, [onError])
const setValue = useCallback((newValue: string) => {
setValueInternal(newValue)
onChange?.(newValue)
}, [onChange])
const reset = useCallback(() => {
setValueInternal(initialValue)
}, [initialValue])
return {
value,
setValue,
reset,
isValid: value.length > 0,
}
}
export default useHookName
3. Update index.ts
export { useHookName } from './useHookName'
export type { UseHookNameOptions, UseHookNameReturn } from './useHookName'
Checklist
Project Integration
import { PROJECT_CONSTRAINTS, FORM_ERROR_MESSAGES } from '@/lib/form-constants'
import { ApiError } from '@/lib/api-client'
For advanced patterns (API hooks, form integration, compound hooks), see reference.md.