en un clic
hook
Generate a custom React hook with proper memoization
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Menu
Generate a custom React hook with proper memoization
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Basé sur la classification professionnelle SOC
Generate a new React component with Mantine styling
Update documentation after implementing features or making changes
Run a quick architecture review via architect-reviewer agent
Generate mobile-specific React components with platform detection and safe areas
Run a quick security audit on recent changes or specific files
Generate a test file for a component, hook, or utility
| name | hook |
| description | Generate a custom React hook with proper memoization |
Generates a custom React hook following Skelenote patterns.
useTaskFilters, usePinnedObjects)src/hooks/use{HookName}.ts:
import { useMemo, useCallback } from 'react';
import { useObjects } from '@/contexts';
export interface UseHookNameReturn {
data: SomeType[];
action1: () => void;
action2: (param: string) => void;
isLoading: boolean;
}
export function useHookName(): UseHookNameReturn {
const { store, dataVersion, refreshData } = useObjects();
// Derived data with useMemo
const data = useMemo(() => {
return store.getAll().filter(/* ... */);
}, [store, dataVersion]);
// Actions with useCallback
const action1 = useCallback(() => {
// Implementation
refreshData();
}, [refreshData]);
const action2 = useCallback((param: string) => {
// Implementation
refreshData();
}, [refreshData]);
return {
data,
action1,
action2,
isLoading: false,
};
}
// src/hooks/usePinnedObjects.ts
import { useMemo, useCallback } from 'react';
import { useObjects } from '@/contexts';
import { SkelenoteObject } from '@/lib/loro';
export interface UsePinnedObjectsReturn {
pinnedObjects: SkelenoteObject[];
pin: (objectId: string) => void;
unpin: (objectId: string) => void;
isPinned: (objectId: string) => boolean;
togglePin: (objectId: string) => void;
}
export function usePinnedObjects(): UsePinnedObjectsReturn {
const { store, dataVersion, refreshData } = useObjects();
const pinnedObjects = useMemo(() => {
return store.getAll().filter((obj) => obj.pinned);
}, [store, dataVersion]);
const pinnedIds = useMemo(
() => new Set(pinnedObjects.map((obj) => obj.id)),
[pinnedObjects]
);
const pin = useCallback(
(objectId: string) => {
store.update(objectId, { pinned: true });
refreshData();
},
[store, refreshData]
);
const unpin = useCallback(
(objectId: string) => {
store.update(objectId, { pinned: false });
refreshData();
},
[store, refreshData]
);
const isPinned = useCallback(
(objectId: string) => pinnedIds.has(objectId),
[pinnedIds]
);
const togglePin = useCallback(
(objectId: string) => {
if (isPinned(objectId)) {
unpin(objectId);
} else {
pin(objectId);
}
},
[isPinned, pin, unpin]
);
return {
pinnedObjects,
pin,
unpin,
isPinned,
togglePin,
};
}
src/hooks/src/hooks/index.ts if existsconst { store, dataVersion, refreshData } = useObjects();
// Always include dataVersion in dependencies for derived data
const items = useMemo(() => {
return store.getAll();
}, [store, dataVersion]);
const update = useCallback((id: string, data: Partial<SomeType>) => {
store.update(id, { properties: data });
refreshData(); // Always call after mutations
}, [store, refreshData]);
import { useNavigation } from '@/contexts';
const { navigateTo, currentView } = useNavigation();
const filteredItems = useMemo(() => {
return items.filter((item) => {
if (filter && item.type !== filter) return false;
if (search && !item.title.includes(search)) return false;
return true;
});
}, [items, filter, search]);
src/hooks/useHookName.test.ts:
import { renderHook, act } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { useHookName } from './useHookName';
// Mock contexts as needed
vi.mock('@/contexts', () => ({
useObjects: () => ({
store: mockStore,
dataVersion: 1,
refreshData: vi.fn(),
}),
}));
describe('useHookName', () => {
it('returns expected data', () => {
const { result } = renderHook(() => useHookName());
expect(result.current.data).toEqual([]);
});
});