Claude-skill-registry add-hook-whatifwedigdeeper-application-tracker
Create a custom React hook with TypeScript and tests
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/add-hook-whatifwedigdeeper-application-tracker" ~/.claude/skills/majiayu000-claude-skill-registry-add-hook-whatifwedigdeeper-application-tracker && rm -rf "$T"
manifest:
skills/data/add-hook-whatifwedigdeeper-application-tracker/SKILL.mdsource content
Add Hook: $ARGUMENTS
Create a custom React hook with proper typing and tests.
Process
1. Plan the Hook
Determine:
- What state does it manage?
- What side effects does it handle?
- What does it return?
2. Create Hook File
Location:
hooks/use[HookName].ts
import { useState, useEffect, useCallback } from 'react'; interface UseHookNameOptions { // configuration options initialValue?: string; } interface UseHookNameReturn { // return type value: string; setValue: (value: string) => void; isLoading: boolean; error: Error | null; } export function useHookName(options: UseHookNameOptions = {}): UseHookNameReturn { const { initialValue = '' } = options; const [value, setValue] = useState(initialValue); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState<Error | null>(null); const handleSetValue = useCallback((newValue: string) => { setValue(newValue); }, []); useEffect(() => { // Side effects here }, []); return { value, setValue: handleSetValue, isLoading, error, }; }
3. Add to Exports
// hooks/index.ts export { useHookName } from './useHookName';
4. Create Tests
// hooks/useHookName.test.ts import { renderHook, act } from '@testing-library/react'; import { useHookName } from './useHookName'; describe('useHookName', () => { test('returns initial value', () => { const { result } = renderHook(() => useHookName()); expect(result.current.value).toBe(''); }); test('updates value', () => { const { result } = renderHook(() => useHookName()); act(() => { result.current.setValue('new value'); }); expect(result.current.value).toBe('new value'); }); test('accepts initial value option', () => { const { result } = renderHook(() => useHookName({ initialValue: 'custom' }) ); expect(result.current.value).toBe('custom'); }); });
5. Validate
npm run build npm run lint npm test
Common Hook Patterns
Data fetching:
export function useFetch<T>(url: string) { const [data, setData] = useState<T | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState<Error | null>(null); // ... }
Local storage:
export function useLocalStorage<T>(key: string, initialValue: T) { const [value, setValue] = useState<T>(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initialValue; }); // ... }
Debounce:
export function useDebounce<T>(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState(value); // ... }
Media query:
export function useMediaQuery(query: string): boolean { const [matches, setMatches] = useState(false); // ... }