skills/react-state-and-transition-patterns/SKILL.md
React state management and transition patterns — functional setState, useTransition, useRef for transient values, deferred reads, derived subscriptions, Activity. Use when optimizing state updates, transitions, or reducing unnecessary re-renders.
npx skillsauth add ihj04982/my-cursor-settings react-state-and-transition-patternsInstall 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.
Patterns for efficient state updates, non-blocking transitions, and minimal re-renders.
When new state depends on previous state, use the updater function to prevent stale closures and create stable callbacks.
Bad (requires state as dependency, risk of stale closure):
const addItems = useCallback((newItems: Item[]) => {
setItems([...items, ...newItems]);
}, [items]); // recreated on every items change
Good (stable callback, no stale closures):
const addItems = useCallback((newItems: Item[]) => {
setItems((curr) => [...curr, ...newItems]);
}, []); // never recreated
When direct updates are fine: Setting state to a static value (setCount(0)) or from arguments only (setName(newName)).
Mark frequent, non-urgent state updates as transitions to keep the UI responsive.
Bad (blocks UI on every scroll):
const handler = () => setScrollY(window.scrollY);
Good (non-blocking):
import { startTransition } from 'react';
const handler = () => startTransition(() => setScrollY(window.scrollY));
useTransition provides built-in isPending state, auto error resilience, and interrupt handling.
Bad (manual loading state):
const [isLoading, setIsLoading] = useState(false);
const handleSearch = async (value: string) => {
setIsLoading(true);
const data = await fetchResults(value);
setResults(data);
setIsLoading(false);
};
Good:
const [isPending, startTransition] = useTransition();
const handleSearch = (value: string) => {
setQuery(value);
startTransition(async () => {
const data = await fetchResults(value);
setResults(data);
});
};
Reference: useTransition
Values that change frequently but don't need re-renders (mouse position, timeout IDs, flags) belong in useRef.
Bad (renders every mouse move):
const [lastX, setLastX] = useState(0);
useEffect(() => {
const onMove = (e: MouseEvent) => setLastX(e.clientX);
window.addEventListener('mousemove', onMove);
return () => window.removeEventListener('mousemove', onMove);
}, []);
Good (no re-render, direct DOM update):
const lastXRef = useRef(0);
const dotRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const onMove = (e: MouseEvent) => {
lastXRef.current = e.clientX;
if (dotRef.current) dotRef.current.style.transform = `translateX(${e.clientX}px)`;
};
window.addEventListener('mousemove', onMove);
return () => window.removeEventListener('mousemove', onMove);
}, []);
Don't subscribe to dynamic state if you only read it inside callbacks.
Bad (subscribes to all searchParams changes):
const searchParams = useSearchParams();
const handleShare = () => {
const ref = searchParams.get('ref');
shareChat(chatId, { ref });
};
Good (reads on demand, no subscription):
const handleShare = () => {
const params = new URLSearchParams(window.location.search);
const ref = params.get('ref');
shareChat(chatId, { ref });
};
Subscribe to derived boolean state instead of continuous values to reduce re-render frequency.
Bad (re-renders on every pixel change):
const width = useWindowWidth();
const isMobile = width < 768;
Good (re-renders only when boolean changes):
const isMobile = useMediaQuery('(max-width: 767px)');
Use React's <Activity> to preserve state/DOM for expensive components that frequently toggle visibility.
import { Activity } from 'react';
function Dropdown({ isOpen }: Props) {
return (
<Activity mode={isOpen ? 'visible' : 'hidden'}>
<ExpensiveMenu />
</Activity>
);
}
Avoids expensive re-renders and state loss on toggle.
startTransitionuseTransition instead of manual useStateuseRef<Activity>development
Conduct WCAG 2.2 accessibility audits with automated testing, manual verification, and remediation guidance. Use when auditing websites for accessibility, fixing WCAG violations, or implementing accessible design patterns.
research
Generate high-entropy research (자료조사) and ideas (아이디어) using Verbalized Sampling to avoid mode collapse and maximize creativity and novelty.
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.
documentation
Sync documentation from source-of-truth (package.json, .env.example). Generates CONTRIB.md, RUNBOOK.md. Use when updating project docs or after adding scripts/env vars.