一键导入
react-hook
Use when passing callbacks to custom hooks, fixing react-hooks/exhaustive-deps warnings, or debugging unexpected re-renders in React components.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when passing callbacks to custom hooks, fixing react-hooks/exhaustive-deps warnings, or debugging unexpected re-renders in React components.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Launch recipe for the daily-writing-friends web app (apps/web — Vite + React + React Router, dev server on http://localhost:5173). Use to build and run the app locally so /run and /verify can drive the real UI. Captures the mandatory nvm node-22 PATH prefix (the default Homebrew node is broken), the dev-server command and port, backend selection (cloud vs local Supabase), and the static gate commands (type-check, tests).
Use after UI/frontend changes — layout, responsive behavior, navigation/routing, or any user-facing flow — to prove it actually works by driving a real headless browser (Playwright) against the running dev server. Asserts behavior (clicks, URL changes, visible text), measures layout (alignment via bounding boxes, overflow via scrollWidth minus clientWidth), captures console/page errors, and saves screenshots. Reach for this whenever "it type-checks and the unit tests pass" does not prove the feature renders and behaves correctly in a browser. Complements verify-runtime (which checks data-flow via dev logs).
Use when writing or modifying page-level layout markup in apps/web — max-width containers, flex rows, vertical spacing — or composing multiple sections on a page. Enforces shared/ui layout primitives (ReadingColumn, Stack, Row) and compound-component slots over scattered Tailwind classes.
Use when the user wants to improve daily-writing-friends production Web Vital scores (LCP/FCP/CLS) by running additional iterations of the local perf harness to drive the overall F2 score higher. Triggers - "web vital 개선", "LCP 줄여", "F2 점수 올려", "harness 한 번 더 돌려", "perf 개선 작업", "perf iteration", "drive score up".
Fetch and compare per-route p75 Web Vitals (LCP/FCP/CLS) from Sentry Discover for the daily-writing-friends production project, with an F2-weighted score and pre/post-deploy diff. Use when the user wants to verify whether performance improved or regressed after a deploy, compare pre/post-merge windows for a PR, identify the worst-performing routes for the next perf push, or sanity-check a Web Vitals claim. Triggers - "web vital 확인해줘", "p75 비교", "회귀 있나", "perf 점수", "이 PR 머지 후 LCP 어떻게 됐어", "sentry에서 가져와".
Use when writing tests for React components or custom hooks that touch the React Query cache, MSW-mocked Supabase, or React Router data-router loaders. Triggers - writing component tests, writing hook tests that need a provider tree, creating MSW handlers, render() + screen assertions, data-fetching component tests, form integration tests, loader/errorElement tests, optimistic-mutation tests. Does NOT cover pure-function unit tests (use the testing skill) or cross-page journeys (use Playwright E2E).
| name | react-hook |
| description | Use when passing callbacks to custom hooks, fixing react-hooks/exhaustive-deps warnings, or debugging unexpected re-renders in React components. |
Core principles:
useCallback| Rule | Why |
|---|---|
Must start with use | React's hook detection |
| One hook per file | Maintainability |
| Never call conditionally | Breaks hook order |
| Never return side effects | Unpredictable behavior |
| Type inputs and outputs | Clarity and safety |
| Test in isolation | Reliability |
On memoization: Only use useMemo/useCallback when logic is computationally heavy. Otherwise they degrade readability without meaningful benefit. Exception: callbacks passed TO hooks (see stability section below).
react-hooks/exhaustive-deps ESLint warningsaddRange(): The given range isn't in documentInline callback → Hook depends on it → Hook's output in useMemo → Cascade of re-renders
When you fix an ESLint exhaustive-deps warning by adding a dependency, check if that dependency is STABLE. If not, you've created a re-render loop.
// ❌ BAD - inline function recreated every render
const { handler } = useCustomHook({
onComplete: (result) => doSomething(result)
});
// ✅ GOOD - stable reference
const onComplete = useCallback((result) => doSomething(result), []);
const { handler } = useCustomHook({ onComplete });
| Situation | Action |
|---|---|
| Passing callback to hook | Wrap in useCallback |
| ESLint says add dependency | Check if dependency is stable first |
| Hook output changes every render | Trace dependency chain backwards |
| Component re-renders on every keystroke | Check for inline callbacks in hook calls |
If you're about to:
useMemo/useCallback deps without checking stabilitySTOP. Trace the dependency chain. Is everything stable?
| Mistake | Fix |
|---|---|
| "ESLint said add it, so I did" | Check if the dep is stable BEFORE adding |
| "It's just a small callback" | Size doesn't matter, stability does |
| "The hook should handle this" | Caller is responsible for stable refs |
When something re-renders unexpectedly:
useMemo/useCallback that's recreatinguseCallback with stable depsThe bug: Quill editor threw addRange(): The given range isn't in document on every keystroke.
Root cause:
useMemo deps from [toast] to [imageHandler]imageHandler depended on insertImage via useCallbackinsertImage was inline (new function every render)insertImage ↻ imageHandler ↻ modules ↻ ReactQuill re-initFix: Wrap insertImage in useCallback with [] deps.
Time saved by knowing pattern: 2+ hours of debugging → 5 minutes.