.claude/skills/you-might-not-need-an-effect/SKILL.md
Analyze code for useEffect anti-patterns and refactor to simpler alternatives. Use when the user says "you might not need an effect", "check effects", "useEffect audit", or asks to review useEffect usage.
npx skillsauth add bitsocialnet/bitsocial-web you-might-not-need-an-effectInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Analyze code for useEffect anti-patterns and refactor to simpler, more correct alternatives.
Based on https://react.dev/learn/you-might-not-need-an-effect
diff to main, src/components/, whole codebasetrue). Set to false to only propose changes.Determine scope — get the relevant code:
git diff for uncommitted changes.tsx/.ts files for useEffectScan for anti-patterns — check each useEffect against the patterns below
Fix or propose — depending on the fix argument:
fix=true: apply the refactors, then verify with yarn build:verify && yarn lint && yarn typecheckfix=false: list each anti-pattern found with a before/after code suggestionReport — summarize what was found and changed
If you're computing something from existing props or state, calculate it during render.
// ❌ Anti-pattern
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ✅ Fix — derive during render
const fullName = firstName + ' ' + lastName;
// ❌ Anti-pattern
const [filtered, setFiltered] = useState([]);
useEffect(() => {
setFiltered(items.filter(item => item.active));
}, [items]);
// ✅ Fix — calculate during render (useMemo only if profiling shows it's needed)
const filtered = items.filter(item => item.active);
// ❌ Anti-pattern
useEffect(() => {
setComment('');
}, [postCid]);
// ✅ Fix — use key on the component to reset state
<CommentForm key={postCid} />
This project uses plebbit-react-hooks for all data fetching. Never use useEffect + fetch.
// ❌ Anti-pattern
const [comment, setComment] = useState(null);
useEffect(() => {
fetchComment(cid).then(setComment);
}, [cid]);
// ✅ Fix — use the hook
const { state, ...comment } = useComment({ commentCid: cid });
// ❌ Anti-pattern
const [theme, setTheme] = useState('light');
useEffect(() => {
const unsub = settingsStore.subscribe((s) => setTheme(s.theme));
return unsub;
}, []);
// ✅ Fix — use the Zustand store directly
const theme = useSettingsStore((s) => s.theme);
// ❌ Anti-pattern — fires on every render, not on user action
useEffect(() => {
logPageView(pageName);
}, [pageName]);
// ✅ Fix — call in the event handler or route change callback
const navigate = () => {
logPageView(pageName);
router.push(path);
};
// ❌ Anti-pattern
useEffect(() => {
initializeAnalytics();
}, []);
// ✅ Fix — module-level init (runs once on import)
if (typeof window !== 'undefined') {
initializeAnalytics();
}
| useEffect pattern | Replace with |
| --------------------------- | ----------------------------------------------------------------------- |
| Fetch data | useComment, useFeed, useSubplebbit, etc. from plebbit-react-hooks |
| Sync shared state | Zustand store in src/stores/ |
| Derive values from state | Calculate during render |
| Boolean loading/error flags | state field from plebbit-react-hooks, or state machine in Zustand |
Not every effect is wrong. Keep useEffect for:
development
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
data-ai
Add or update i18next translation keys across all language files by spawning translator subagents. Use when the user asks to add a new translation, update existing translations, translate text, or work with i18n keys. Triggers on "translate", "add translation", "translation key", "i18n", "localization".
development
Test and debug Android wrapper features for Bitsocial Web using a local Android emulator or attached device. Manages emulator lifecycle, builds and installs the wrapper when commands are provided, runs focused checks, captures logcat diagnostics, and debugs WebView or TWA behavior. Use when the user asks to test Android, debug WebView behavior, run emulator tests, or says "test-apk".
testing
Review an open GitHub pull request, inspect bot and human feedback, decide which findings are valid, implement fixes on the PR branch, and merge the PR into master when it is ready. Use when the user says "check the PR", "address review comments", "review PR feedback", or "merge this PR".