Skip to main content
react-effect-and-handler-patterns React effect and event handler optimization — narrow deps, handler refs, useEffectEvent, global listener dedup, one-time init. Use when writing or fixing useEffect, event handlers, or component initialization.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/ihj04982/my-cursor-settings --skill react-effect-and-handler-patternsLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Plus depuis ce dépôt Use when the task asks for a visually strong landing page, website, app, prototype, demo, or game UI. This skill enforces restrained composition, image-led hierarchy, cohesive content structure, and tasteful motion while avoiding generic cards, weak branding, and UI clutter.
Automate browser interactions, test web pages and work with Playwright tests.
Advanced guidelines and best practices for writing tests using Vitest. Apply this skill when generating, reviewing, or refactoring test codes to prevent common pitfalls and ensure high performance.
Basé sur la classification professionnelle SOC
name react-effect-and-handler-patterns description React effect and event handler optimization — narrow deps, handler refs, useEffectEvent, global listener dedup, one-time init. Use when writing or fixing useEffect, event handlers, or component initialization.
React Effect & Handler Patterns
Patterns for efficient useEffect usage, stable event handler references, and proper initialization.
1. Narrow Effect Dependencies
Specify primitive dependencies instead of objects to minimize effect re-runs.
Bad (re-runs on any user field change):
useEffect (() => {
console .log (user.id );
}, [user]);
Good (re-runs only when id changes):
useEffect (() => {
console .log (user.id );
}, [user.id ]);
Derive booleans from continuous values:
useEffect (() => {
if (width < 768 ) enableMobileMode ();
}, [width]);
const isMobile = width < 768 ;
( {
(isMobile) ();
}, [isMobile]);
useEffect
() =>
if
enableMobileMode
2. Put Interaction Logic in Event Handlers If a side effect is triggered by a specific user action, run it in the handler — not as state + effect.
Bad (event modeled as state + effect):
const [submitted, setSubmitted] = useState (false );
const theme = useContext (ThemeContext );
useEffect (() => {
if (submitted) {
post ('/api/register' );
showToast ('Registered' , theme);
}
}, [submitted, theme]);
const theme = useContext (ThemeContext );
function handleSubmit ( ) {
post ('/api/register' );
showToast ('Registered' , theme);
}
3. Store Event Handlers in Refs Store callbacks in refs when used in effects that shouldn't re-subscribe on callback changes.
Bad (re-subscribes on every render):
function useWindowEvent (event : string , handler : (e) => void ) {
useEffect (() => {
window .addEventListener (event, handler);
return () => window .removeEventListener (event, handler);
}, [event, handler]);
}
Good (stable subscription):
function useWindowEvent (event : string , handler : (e) => void ) {
const handlerRef = useRef (handler);
useEffect (() => { handlerRef.current = handler; }, [handler]);
useEffect (() => {
const listener = (e ) => handlerRef.current (e);
window .addEventListener (event, listener);
return () => window .removeEventListener (event, listener);
}, [event]);
}
4. useEffectEvent for Stable Callback Refs useEffectEvent provides a cleaner API: a stable function that always calls the latest handler without being in effect deps.
Bad (effect re-runs on every callback change):
useEffect (() => {
const timeout = setTimeout (() => onSearch (query), 300 );
return () => clearTimeout (timeout);
}, [query, onSearch]);
import { useEffectEvent } from 'react' ;
const onSearchEvent = useEffectEvent (onSearch);
useEffect (() => {
const timeout = setTimeout (() => onSearchEvent (query), 300 );
return () => clearTimeout (timeout);
}, [query]);
5. Deduplicate Global Event Listeners Register global event listeners once and share across component instances.
Bad (N instances = N listeners):
function useKeyboardShortcut (key : string , callback : () => void ) {
useEffect (() => {
const handler = (e : KeyboardEvent ) => {
if (e.metaKey && e.key === key) callback ();
};
window .addEventListener ('keydown' , handler);
return () => window .removeEventListener ('keydown' , handler);
}, [key, callback]);
}
Good (N instances = 1 listener via module-level Map + useSWRSubscription):
const keyCallbacks = new Map <string , Set <() => void >>();
function useKeyboardShortcut (key : string , callback : () => void ) {
useEffect (() => {
if (!keyCallbacks.has (key)) keyCallbacks.set (key, new Set ());
keyCallbacks.get (key)!.add (callback);
return () => {
const set = keyCallbacks.get (key);
if (set) { set.delete (callback); if (set.size === 0 ) keyCallbacks.delete (key); }
};
}, [key, callback]);
useSWRSubscription ('global-keydown' , () => {
const handler = (e : KeyboardEvent ) => {
if (e.metaKey && keyCallbacks.has (e.key ))
keyCallbacks.get (e.key )!.forEach ((cb ) => cb ());
};
window .addEventListener ('keydown' , handler);
return () => window .removeEventListener ('keydown' , handler);
});
}
6. Initialize App Once, Not Per Mount App-wide init (analytics, auth check) must run once at module load, not inside useEffect([]) which re-runs on remount.
Bad (runs twice in dev, re-runs on remount):
function Comp ( ) {
useEffect (() => {
loadFromStorage ();
checkAuthToken ();
}, []);
}
let didInit = false ;
function Comp ( ) {
useEffect (() => {
if (didInit) return ;
didInit = true ;
loadFromStorage ();
checkAuthToken ();
}, []);
}
Checklist