budtags/skills/react-19/SKILL.md
React 19 changes, new hooks, Actions, Activity component, and migration guides for upgrading from React 18
npx skillsauth add jwilly246/budtags-claude-plugin react-19Install 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.
Comprehensive documentation for React 19 changes, including new hooks, Actions, forms, and migration guides.
| Version | Release Date | Key Features |
|---------|--------------|--------------|
| 19.0 | Dec 5, 2024 | Actions, new hooks, ref changes, Context simplification |
| 19.1 | Mar 28, 2025 | Owner Stack debugging, captureOwnerStack API |
| 19.2 | Oct 1, 2025 | Activity component, useEffectEvent, Performance Tracks |
Our stack: Laravel + Inertia.js + React + TypeScript
| React 19 Feature | BudTags Relevance |
|------------------|-------------------|
| useActionState | ⚠️ Compare to Inertia useForm - similar pending/error handling |
| useOptimistic | ✅ Great for quick actions (finish package, adjust inventory) |
| useFormStatus | ✅ Useful for submit button components |
| use() | ✅ Can complement React Query for promise handling |
| useEffectEvent | ✅ Solves common dependency array issues |
| Activity | ✅ Perfect for tabs, modals that preserve state |
| Server Components | ❌ Not applicable - we use Laravel controllers |
| Server Actions | ❌ Not applicable - we use Inertia forms/axios |
| Metadata hoisting | ⚠️ Inertia's <Head> component handles this |
Load only the patterns you need:
patterns/01-upgrade-guide.md
patterns/14-breaking-changes.md
migrations/from-18-to-19.md
patterns/02-new-hooks.md
patterns/03-actions-forms.md
patterns/04-use-api.md
patterns/03-actions-forms.md
patterns/02-new-hooks.md (useFormStatus section)
patterns/11-activity-component.md
patterns/12-use-effect-event.md
patterns/13-performance-tracks.md
// useActionState - Handle async form actions
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get("name"));
if (error) return error;
redirect("/path");
return null;
},
null
);
// useOptimistic - Optimistic UI updates
const [optimisticName, setOptimisticName] = useOptimistic(currentName);
// useFormStatus - Access parent form state
function SubmitButton() {
const { pending } = useFormStatus();
return <button disabled={pending}>Submit</button>;
}
// use() - Read promises/context (can be conditional!)
function Comments({ commentsPromise }) {
const comments = use(commentsPromise); // Suspends until resolved
return comments.map(c => <p key={c.id}>{c.text}</p>);
}
// OLD - forwardRef (deprecated)
const MyInput = forwardRef(function MyInput({ placeholder }, ref) {
return <input placeholder={placeholder} ref={ref} />;
});
// NEW - ref as regular prop
function MyInput({ placeholder, ref }) {
return <input placeholder={placeholder} ref={ref} />;
}
// NEW - Ref cleanup functions
<input ref={(el) => {
// Setup
return () => {
// Cleanup (instead of receiving null)
};
}} />
// OLD
<ThemeContext.Provider value="dark">
{children}
</ThemeContext.Provider>
// NEW
<ThemeContext value="dark">
{children}
</ThemeContext>
// Hide content without destroying state
<Activity mode={isVisible ? 'visible' : 'hidden'}>
<ExpensiveComponent />
</Activity>
// Modes:
// - 'visible': Normal rendering, effects mounted
// - 'hidden': Hidden, effects unmounted, updates deferred
// Problem: theme in deps causes reconnects
useEffect(() => {
connection.on('connected', () => showNotification(theme));
// ...
}, [roomId, theme]); // theme causes unnecessary effect runs
// Solution: Extract event logic
const onConnected = useEffectEvent(() => {
showNotification(theme); // Always reads latest theme
});
useEffect(() => {
connection.on('connected', onConnected);
// ...
}, [roomId]); // Clean deps!
01-upgrade-guide.md - Step-by-step upgrade from React 1814-breaking-changes.md - All breaking changes and migrations02-new-hooks.md - useActionState, useOptimistic, useFormStatus03-actions-forms.md - Form action prop, automatic handling04-use-api.md - use() for promises and context05-ref-changes.md - ref as prop, cleanup functions06-context-changes.md - Simplified Context provider07-metadata-stylesheets.md - Metadata hoisting, stylesheet precedence08-resource-preloading.md - prefetchDNS, preconnect, preload, preinit09-error-handling.md - Improved errors, new root callbacks10-suspense-hydration.md - useDeferredValue, hydration improvements11-activity-component.md - Activity for hidden/visible UI12-use-effect-event.md - Extract event logic from effects13-performance-tracks.md - Chrome DevTools integrationmigrations/from-18-to-19.md - Full 18→19 migration guidemigrations/19-to-19-1.md - 19.0→19.1 changesmigrations/19-1-to-19-2.md - 19.1→19.2 changesnpm install react@19 react-dom@19npx types-react-codemod@latestforwardRef with ref propref={r => (x = r)} → ref={r => {x = r}}<Context.Provider> to <Context>useFormState to useActionStatenpm install eslint-plugin-react-hooks@latest<Activity> for tab/modal state preservationuseEffectEvent where appropriatedevelopment
Use this skill when generating ZPL code, working with ZPL commands, creating Zebra printer labels, or troubleshooting ZPL syntax and formatting issues.
development
Use this skill to verify that code aligns with BudTags coding standards, architectural patterns, and conventions before or after implementation.
development
Use this skill when working with Unleashed Software inventory/order management API integration, syncing inventory, importing orders, managing stock adjustments, or handling customer/product data from Unleashed.
data-ai
TanStack Virtual patterns for virtualized lists, tables, and grids with high-performance rendering of large datasets