Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计通过

use-effect-killer使用效果杀手

Agent Skill

use-effect-killer 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

989

周安装

40

GitHub Stars

10

下载量

310
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:use-effect-killer(使用效果杀手)
来源仓库:https://github.com/victor36max/use-effect-killer
仓库路径:skills/use-effect-killer
安装命令:
npx skills add https://github.com/victor36max/use-effect-killer --skill use-effect-killer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/victor36max/use-effect-killer --skill use-effect-killer

简介

use-effect-killer 用于查找、检索和筛选相关信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词或任务场景快速定位候选结果。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装并使用。
  • 安装前需确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。
  • 建议结合来源仓库和原始 README 核验具体用法和功能边界。

SKILL.md

useEffect Killer

Audit a React codebase for unnecessary or misused useEffect calls and propose idiomatic alternatives.

Reference: https://react.dev/learn/you-might-not-need-an-effect

Workflow

  1. Find all useEffect usages. Grep for useEffect across $ARGUMENTS (or the entire repo if no path given). Filter to .tsx, .ts, .jsx, .js files.
  2. Read each file containing useEffect. For every useEffect call, classify it against the anti-pattern catalog below. Skip effects that are legitimate (event listeners with cleanup for component-scoped DOM, animation setup, true synchronization with external systems).
  3. For each finding, record:

- File path and line number - Which anti-pattern it matches - The problematic code snippet - A concrete suggested fix using the recommended alternative

  1. Report findings using the output format at the bottom. Group by anti-pattern. Include a summary with counts.
  2. If $ARGUMENTS is empty, scan all React component files in the project.

Anti-Pattern Catalog

Use these patterns to classify each useEffect you encounter.

1. Derived State

State that is computed from other state or props, updated via useEffect.

Detect: useEffect body calls a setter, and the value being set can be expressed as a pure function of state/props already available during render.

Bad:

const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [fullName, setFullName] = useState('');
useEffect(() => {
  setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);

Fix: Remove the extra state and effect. Compute inline.

const fullName = firstName + ' ' + lastName;

2. Expensive Derived Computation

Same as #1 but the computation is expensive, so the developer reached for useEffect + state to "cache" it.

Detect: useEffect that transforms or filters data from props/state into another state variable. Often involves .filter(), .map(), .sort(), .reduce().

Bad:

const [visibleTodos, setVisibleTodos] = useState([]);
useEffect(() => {
  setVisibleTodos(getFilteredTodos(todos, filter));
}, [todos, filter]);

Fix: Use useMemo.

const visibleTodos = useMemo(
  () => getFilteredTodos(todos, filter),
  [todos, filter]
);

3. Reset All State on Prop Change

Using useEffect to reset state variables when an identity prop (e.g., userId, itemId) changes.

Detect: useEffect whose body sets one or more state variables to initial values, with a prop in the dependency array.

Bad:

function ProfilePage({ userId }) {
  const [comment, setComment] = useState('');
  useEffect(() => {
    setComment('');
  }, [userId]);

Fix: Extract into a child component and use key to reset.

function ProfilePage({ userId }) {
  return <Profile userId={userId} key={userId} />;
}
function Profile({ userId }) {
  const [comment, setComment] = useState('');

4. Adjust Some State on Prop Change

Using useEffect to partially update state when props change, but not a full reset.

Detect: useEffect with a prop dependency that conditionally updates state — often nulling out a selection or resetting a sub-field.

Bad:

function List({ items }) {
  const [selection, setSelection] = useState(null);
  useEffect(() => {
    setSelection(null);
  }, [items]);

Fix (preferred): Derive the value during render instead of storing it.

function List({ items }) {
  const [selectedId, setSelectedId] = useState(null);
  const selection = items.find(item => item.id === selectedId) ?? null;

Fix (alternative): Store previous props and adjust during render. Note: the items!== prevItems guard is mandatory — without it, you get an infinite render loop. This pattern also triggers one extra re-render.

const [prevItems, setPrevItems] = useState(items);
if (items !== prevItems) {
  setPrevItems(items);
  setSelection(null);
}

5. Event Logic in Effect

Side effects (toast, notification, navigation, analytics for a user action) placed in useEffect instead of in the event handler that triggered them.

Detect: useEffect that calls functions like showNotification, toast, navigate, router.push, alert, or logs analytics — triggered by a state variable that was set in an event handler.

Bad:

useEffect(() => {
  if (product.isInCart) {
    showNotification(`Added ${product.name} to cart!`);
  }
}, [product]);

Fix: Move into the event handler.

function handleBuyClick() {
  addToCart(product);
  showNotification(`Added ${product.name} to cart!`);
}

6. POST / Mutation in Effect

Using a state variable as a trigger to fire a network request from useEffect.

Detect: useEffect that calls fetch, post, axios, mutate, useMutation, tRPC mutations, or similar — where the dependency is a state variable set by an event handler (often a "submit payload" state).

Bad:

const [jsonToSubmit, setJsonToSubmit] = useState(null);
useEffect(() => {
  if (jsonToSubmit !== null) {
    post('/api/register', jsonToSubmit);
  }
}, [jsonToSubmit]);

Fix: Call directly from the event handler.

function handleSubmit(e) {
  e.preventDefault();
  post('/api/register', { firstName, lastName });
}

7. Effect Chains

Multiple useEffects where one sets state that triggers the next, forming a cascade.

Detect: Two or more useEffect calls in the same component where the dependency of one includes a state variable set inside another. Look for sequential state-setting patterns.

Bad:

useEffect(() => { if (card?.gold) setGoldCardCount(c => c + 1); }, [card]);
useEffect(() => { if (goldCardCount > 3) { setRound(r => r + 1); setGoldCardCount(0); } }, [goldCardCount]);
useEffect(() => { if (round > 5) setIsGameOver(true); }, [round]);

Fix: Derive what you can (const isGameOver = round > 5), consolidate the rest into the event handler.

const isGameOver = round > 5;

function handlePlaceCard(nextCard) {
  setCard(nextCard);
  if (nextCard.gold) {
    if (goldCardCount < 3) {
      setGoldCardCount(goldCardCount + 1);
    } else {
      setGoldCardCount(0);
      setRound(round + 1);
    }
  }
}

8. App Initialization in Effect

One-time setup code (auth checks, localStorage reads, config loading) inside a useEffect([],...) that breaks under Strict Mode double-mount.

Detect: useEffect with [] dependency array that runs init-style logic: auth token checks, localStorage reads, global config. Especially problematic if the logic has side effects that shouldn't run twice.

Bad:

useEffect(() => {
  loadDataFromLocalStorage();
  checkAuthToken();
}, []);

Fix: Guard with a module-level flag so it runs once, even under Strict Mode double-mount.

let didInit = false;

function App() {
  useEffect(() => {
    if (!didInit) {
      didInit = true;
      loadDataFromLocalStorage();
      checkAuthToken();
    }
  }, []);
}

For code that truly has no side effects and doesn't need React lifecycle, module-level execution is also valid:

if (typeof window !== 'undefined') {
  // Only for pure reads — not for auth tokens or anything with side effects
  const cachedTheme = localStorage.getItem('theme');
}

9. Notify Parent via Effect

Calling a parent callback (like onChange) inside useEffect after a state update, instead of alongside it.

Detect: useEffect whose body calls a prop callback (onChange, onUpdate, onSelect, etc.) passing the current state value.

Bad:

function Toggle({ onChange }) {
  const [isOn, setIsOn] = useState(false);
  useEffect(() => {
    onChange(isOn);
  }, [isOn, onChange]);

Fix: Call the callback in the event handler.

function handleClick() {
  const nextIsOn = !isOn;
  setIsOn(nextIsOn);
  onChange(nextIsOn);
}

Or make the component fully controlled (remove local state, let parent own it).

10. Pass Data to Parent via Effect

Child fetches or computes data, then pushes it up to the parent through an effect callback.

Detect: useEffect calling a prop callback like onFetched, onData, onLoaded with data obtained from a hook or fetch inside the child.

Bad:

function Child({ onFetched }) {
  const data = useSomeAPI();
  useEffect(() => {
    if (data) onFetched(data);
  }, [onFetched, data]);

Fix: Lift the data fetching to the parent. Pass data down, not up.

function Parent() {
  const data = useSomeAPI();
  return <Child data={data} />;
}

11. External Store Subscription

Manual addEventListener/removeEventListener or subscription logic inside useEffect to sync with browser APIs or external stores.

Detect: useEffect with addEventListener/removeEventListener on window, document, or navigator (not on a component ref) that syncs external state into React state. Also .subscribe() / .unsubscribe() patterns for global stores. Do NOT flag ref-scoped DOM listeners with proper cleanup — those are legitimate.

Bad:

useEffect(() => {
  function update() { setIsOnline(navigator.onLine); }
  window.addEventListener('online', update);
  window.addEventListener('offline', update);
  return () => {
    window.removeEventListener('online', update);
    window.removeEventListener('offline', update);
  };
}, []);

Fix: Use useSyncExternalStore.

const isOnline = useSyncExternalStore(
  (cb) => {
    window.addEventListener('online', cb);
    window.addEventListener('offline', cb);
    return () => {
      window.removeEventListener('online', cb);
      window.removeEventListener('offline', cb);
    };
  },
  () => navigator.onLine,
  () => true
);

12. Initialize State from Props via Effect

Using useEffect to set state from props on first render, instead of passing the prop to useState directly.

Detect: useEffect with [] dependency that calls a setter with a prop value, or useEffect with [prop] where the state has a different initial value (like null) and is immediately overwritten.

Bad:

function Editor({ initialContent }) {
  const [content, setContent] = useState(null);
  useEffect(() => {
    setContent(initialContent);
  }, []);
}

Fix: Pass the prop directly as the initial state value.

function Editor({ initialContent }) {
  const [content, setContent] = useState(initialContent);
}

This eliminates the flicker where the component first renders with null, then immediately re-renders with the prop value.

13. Fetch Without Cleanup

Data fetching in useEffect without handling stale responses (race conditions).

Detect: useEffect containing fetch, axios, or async calls that set state on completion — without a cleanup function that sets an ignore flag or calls AbortController.abort().

Bad:

useEffect(() => {
  fetchResults(query).then(json => {
    setResults(json);
  });
}, [query]);

Fix: Add an ignore flag or abort controller. Better yet, use a data-fetching library (TanStack Query, SWR, etc.).

useEffect(() => {
  let ignore = false;
  fetchResults(query).then(json => {
    if (!ignore) setResults(json);
  });
  return () => { ignore = true; };
}, [query]);

Legitimate useEffect Usages (Do NOT Flag)

Skip these — they are valid uses of useEffect:

  • Subscribing to ref-scoped DOM events with proper cleanup (e.g., ResizeObserver on a specific element ref, IntersectionObserver on a ref). Note: window/document-level subscriptions that drive render state should use useSyncExternalStore instead (see #11).
  • Running animations or timers scoped to component mount
  • Synchronizing with truly external systems (WebSocket connections, third-party widget initialization)
  • Analytics/logging that should fire on component display (not on a user action)
  • Focus management on mount

Output Format

Structure your report as follows:

## useEffect Audit Results

### Summary
- **Files scanned:** N
- **useEffect instances found:** N
- **Anti-patterns detected:** N
- **Legitimate usages (skipped):** N

### Findings

#### 1. Derived State (X found)

**`src/components/UserProfile.tsx:42`**
(show the current code)
**Problem:** fullName is derived from first and last — no effect needed.
**Fix:** `const fullName = first + ' ' + last;` and remove the `fullName` state.

---
(repeat for each finding, grouped by anti-pattern)

### Clean Files
Files with useEffect that passed review — list briefly so the user knows they were checked.

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

35.34%
按下载量换算110

Claude

31.47%
按下载量换算98

Cursor

18.93%
按下载量换算59

Gemini CLI

10.15%
按下载量换算31

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills