.codex/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/5chan 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 && yarn lint && yarn type-checkfix=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 bitsocial-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 bitsocial-react-hooks |
| Sync shared state | Zustand store in src/stores/ |
| Derive values from state | Calculate during render |
| Boolean loading/error flags | state field from bitsocial-react-hooks, or state machine in Zustand |
Not every effect is wrong. Keep useEffect for:
tools
Profile app performance while browsing, collecting Web Vitals and React rerender data via react-scan. Orchestrates parallel profiler subagents via playwright-cli to capture navigation timing, long tasks, layout shifts, LCP, React commit counts, render bursts, and per-component render data. Use when profiling browsing performance, finding bottlenecks, diagnosing excessive rerenders, or auditing page performance.
tools
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
tools
Create a GitHub issue from recent changes, commit only relevant diffs on a short-lived task branch, push that branch, and open a PR into master that will close the issue on merge. Use when the user says "make closed issue", "close issue", or wants to create a tracked, already-resolved GitHub issue for completed work.
development
Formats GitHub issue titles and descriptions for tracking problems that were fixed. Use when proposing or implementing code changes, creating GitHub issues, or when the user asks for issue suggestions.