mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
Fixes deslop diffing against nonexistent main, an invalid rg --type tsx flag in fix-merge-conflicts, a Codex-specific phrase leaking into the Claude/Cursor inspect-elements description, and aligns commit-format with the required-scope convention the commit skill and git history already use. Rewrites the readme skill from 764 lines of Rails-specific guidance to a lean version matching this Vite/Capacitor/Electron repo.
4.4 KiB
4.4 KiB
name, description, disable-model-invocation
| name | description | disable-model-invocation |
|---|---|---|
| you-might-not-need-an-effect | 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. | true |
You Might Not Need an Effect
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
Arguments
- scope: what to analyze (default: uncommitted changes). Examples:
diff to master,src/components/,whole codebase - fix: whether to apply fixes (default:
true). Set tofalseto only propose changes.
Workflow
-
Determine scope — get the relevant code:
- Default:
git difffor uncommitted changes - If a directory/file is specified, read those files
- If "whole codebase": search all
.tsx/.tsfiles foruseEffect
- Default:
-
Scan for anti-patterns — check each
useEffectagainst the patterns below -
Fix or propose — depending on the
fixargument:fix=true: apply the refactors, then verify withyarn build && yarn lint && yarn type-checkfix=false: list each anti-pattern found with a before/after code suggestion
-
Report — summarize what was found and changed
Anti-Patterns to Catch
1. Deriving state during render (no effect needed)
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;
2. Caching expensive calculations (useMemo, not useEffect)
// ❌ 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);
3. Resetting state when props change (use key, not useEffect)
// ❌ Anti-pattern
useEffect(() => {
setComment('');
}, [postCid]);
// ✅ Fix — use key on the component to reset state
<CommentForm key={postCid} />
4. Fetching data (use bitsocial-react-hooks, not useEffect)
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 });
5. Syncing with external stores (use Zustand, not useEffect)
// ❌ 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);
6. Sending analytics / logging (move to event handlers)
// ❌ 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);
};
7. Initializing global singletons (use module scope or lazy init)
// ❌ Anti-pattern
useEffect(() => {
initializeAnalytics();
}, []);
// ✅ Fix — module-level init (runs once on import)
if (typeof window !== 'undefined') {
initializeAnalytics();
}
Project-Specific Replacements
| useEffect pattern | Replace with |
|---|---|
| Fetch data | useComment, useFeed, useCommunity, 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 |
When useEffect IS Appropriate
Not every effect is wrong. Keep useEffect for:
- Subscribing to browser APIs (resize, intersection observer, etc.) with proper cleanup
- Synchronizing with non-React systems (third-party widgets, imperative DOM)
- Running code on mount that genuinely has no hook equivalent