AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

React 19

skill-noklip-io-agent-skills-react-19 · by noklip-io

>

No reviews yet
0 installs
30 views
0.0% view→install

Install

$ agentstack add skill-noklip-io-agent-skills-react-19

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-noklip-io-agent-skills-react-19)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
7mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of React 19? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

React 19 - Key Changes

This skill focuses on what changed in React 19. Not a complete React reference.

Coming from React 16/17?

If upgrading from pre-18 versions, these changes accumulated and are now mandatory:

| Change | Introduced | React 19 Status | |--------|------------|-----------------| | createRoot / hydrateRoot | React 18 | Required (ReactDOM.render removed) | | Concurrent rendering | React 18 | Foundation for all R19 features | | Automatic batching | React 18 | Default behavior | | useId, useSyncExternalStore | React 18 | Stable, commonly used | | Hooks (no classes for new code) | React 16.8 | Only path for new features | | createContext (not legacy) | React 16.3 | Required (legacy Context removed) | | Error Boundaries | React 16 | Now with better error callbacks |

Migration path: Upgrade to React 18.3 first (shows deprecation warnings), then to 19.

The React 19 Mindset

React 19 represents fundamental shifts in how to think about React:

| Old Thinking | New Thinking | |--------------|--------------| | Client-side by default | Server-first (RSC default) | | Manual memoization | Compiler handles it | | useEffect for data | async Server Components | | useState for forms | Form Actions | | Loading state booleans | Suspense boundaries | | Optimize everything | Write correct code, compiler optimizes |

See [references/paradigm-shifts.md](./references/paradigm-shifts.md) for the mental model changes.

See [references/anti-patterns.md](./references/anti-patterns.md) for what to stop doing.

Quick Reference: What's New

| Feature | React 18 | React 19+ | |---------|----------|-----------| | Memoization | Manual (useMemo, useCallback, memo) | React Compiler (automatic) or manual | | Forward refs | forwardRef() wrapper | ref as regular prop | | Context provider | ` | | | Form state | Custom with useState | useActionState hook | | Optimistic updates | Manual state management | useOptimistic hook | | Read promises | Not possible in render | use() hook | | Conditional context | Not possible | use(Context) after conditionals | | Form pending state | Manual tracking | useFormStatus hook | | Ref cleanup | Pass null on unmount | Return cleanup function | | Document metadata | react-helmet or manual | Native , , | | Hide/show UI with state | Unmount/remount (state lost) | component (19.2+) | | Non-reactive Effect logic | Add to deps or suppress lint | useEffectEvent` hook (19.2+) | | Custom Elements | Partial support | Full support (props as properties) | | Hydration errors | Multiple vague errors | Single error with diff |

React Compiler & Memoization

With React Compiler enabled, manual memoization is optional, not forbidden:

// React Compiler handles this automatically
function Component({ items }) {
  const filtered = items.filter(x => x.active);
  const sorted = filtered.sort((a, b) => a.name.localeCompare(b.name));
  const handleClick = (id) => console.log(id);
  return ;
}

// Manual memoization still works as escape hatch for fine-grained control
const filtered = useMemo(() => expensiveOperation(items), [items]);
const handleClick = useCallback((id) => onClick(id), [onClick]);

When to use manual memoization with React Compiler:

  • Effect dependencies that need stable references
  • Sharing expensive calculations across components (compiler doesn't share)
  • Explicit control over when re-computation happens

See [references/react-compiler.md](./references/react-compiler.md) for details.

ref as Prop (forwardRef Deprecated)

// React 19: ref is just a prop
function Input({ placeholder, ref }) {
  return ;
}

// Usage - no change
const inputRef = useRef(null);

// forwardRef still works but will be deprecated
// Codemod: npx codemod@latest react/19/replace-forward-ref

Ref Cleanup Functions

// React 19: Return cleanup function from ref callback
 {
    // Setup
    node?.focus();
    // Return cleanup (called on unmount or ref change)
    return () => {
      console.log('Cleanup');
    };
  }}
/>

// React 18: Received null on unmount (still works, but cleanup preferred)
 {
  if (node) { /* setup */ }
  else { /* cleanup */ }
}} />

Context as Provider

const ThemeContext = createContext('light');

// React 19: Use Context directly
function App({ children }) {
  return (
    
      {children}
    
  );
}

// React 18: Required .Provider (still works, will be deprecated)

  {children}

New Hooks

useActionState

import { useActionState } from 'react';

function Form() {
  const [error, submitAction, isPending] = useActionState(
    async (prevState, formData) => {
      const result = await saveData(formData.get('name'));
      if (result.error) return result.error;
      redirect('/success');
      return null;
    },
    null // initial state
  );

  return (
    
      
      
        {isPending ? 'Saving...' : 'Save'}
      
      {error && {error}}
    
  );
}

useOptimistic

import { useOptimistic } from 'react';

function Messages({ messages, sendMessage }) {
  const [optimisticMessages, addOptimistic] = useOptimistic(
    messages,
    (state, newMessage) => [...state, { ...newMessage, sending: true }]
  );

  async function handleSubmit(formData) {
    const message = { text: formData.get('text'), id: Date.now() };
    addOptimistic(message); // Show immediately
    await sendMessage(message); // Reverts on error
  }

  return (
    
      {optimisticMessages.map(m => (
        
          {m.text}
        
      ))}
      
    
  );
}

use() Hook

import { use, Suspense } from 'react';

// Read promises (suspends until resolved)
function Comments({ commentsPromise }) {
  const comments = use(commentsPromise);
  return comments.map(c => {c.text});
}

// Usage with Suspense
}>
  

// Conditional context reading (not possible with useContext!)
function Theme({ showTheme }) {
  if (!showTheme) return Plain;

  const theme = use(ThemeContext); // Can be called conditionally!
  return Themed;
}

useFormStatus (react-dom)

import { useFormStatus } from 'react-dom';

// Must be used inside a  - reads parent form status
function SubmitButton() {
  const { pending, data, method, action } = useFormStatus();
  return (
    
      {pending ? 'Submitting...' : 'Submit'}
    
  );
}

function Form() {
  return (
    
      
       {/* Reads form status via context */}
    
  );
}

See [references/new-hooks.md](./references/new-hooks.md) for complete API details.

Form Actions

// Pass function directly to form action
 {
  'use server';
  await saveToDatabase(formData);
}}>
  
  Subscribe

// Button-level actions

  Save
  Delete

// Manual form reset
import { requestFormReset } from 'react-dom';
requestFormReset(formElement);

Document Metadata

// Automatically hoisted to  - works in any component
function BlogPost({ post }) {
  return (
    
      {post.title}
      
      
      
      {post.title}
      {post.content}
    
  );
}

Resource Preloading

import { prefetchDNS, preconnect, preload, preinit } from 'react-dom';

function App() {
  // DNS prefetch
  prefetchDNS('https://api.example.com');

  // Establish connection early
  preconnect('https://fonts.googleapis.com');

  // Preload resources
  preload('https://example.com/font.woff2', { as: 'font' });
  preload('/hero.jpg', { as: 'image' });

  // Load and execute script eagerly
  preinit('https://example.com/analytics.js', { as: 'script' });

  return ...;
}

Stylesheet Support

// precedence controls insertion order and deduplication
function Component() {
  return (
    <>
      
      
      Content
    
  );
}

// React ensures stylesheets load before Suspense boundary reveals
}>
  
  

Custom Elements Support

React 19 adds full support for Custom Elements (Web Components).

// Props matching element properties are assigned as properties
// Others are assigned as attributes

Client-side: React checks if a property exists on the element instance. If yes, assigns as property; otherwise, as attribute.

Server-side (SSR): Primitive types (string, number) render as attributes. Objects, functions, symbols are omitted from HTML.

// Define custom element
class MyElement extends HTMLElement {
  constructor() {
    super();
    this.data = undefined; // React will assign to this property
  }

  connectedCallback() {
    this.textContent = JSON.stringify(this.data);
  }
}
customElements.define('my-element', MyElement);

// Use in React

Hydration Improvements

Better Error Messages

React 19 shows a single error with a diff instead of multiple vague errors:

Uncaught Error: Hydration failed because the server rendered HTML
didn't match the client.

  
+   Client
-   Server

Third-Party Script Compatibility

React 19 gracefully handles elements inserted by browser extensions or third-party scripts:

  • Unexpected tags in ` and ` are skipped (no mismatch errors)
  • Stylesheets from extensions are preserved during re-renders
  • No need to add suppressHydrationWarning for extension-injected content

Removed APIs (Breaking)

| Removed | Migration | |---------|-----------| | ReactDOM.render() | createRoot().render() | | ReactDOM.hydrate() | hydrateRoot() | | unmountComponentAtNode() | root.unmount() | | ReactDOM.findDOMNode() | Use refs | | propTypes | TypeScript or remove | | defaultProps (functions) | ES6 default parameters | | String refs | Callback refs or useRef | | Legacy Context | createContext | | React.createFactory | JSX | | react-dom/test-utils | act from 'react' |

See [references/deprecations.md](./references/deprecations.md) for migration guides.

TypeScript Changes

// useRef requires argument
const ref = useRef(null); // Required
const ref = useRef(); // Error in React 19

// Ref callbacks must not return values (except cleanup)
 { instance = node; }} /> // Correct
 (instance = node)} />    // Error - implicit return

// ReactElement props are now unknown (not any)
type Props = ReactElement['props']; // unknown in R19, any in R18

// JSX namespace - import explicitly
import type { JSX } from 'react';

See [references/typescript-changes.md](./references/typescript-changes.md) for codemods.

Migration Codemods

# Run all React 19 codemods
npx codemod@latest react/19/migration-recipe

# Individual codemods
npx codemod@latest react/19/replace-reactdom-render
npx codemod@latest react/19/replace-string-ref
npx codemod@latest react/19/replace-act-import
npx codemod@latest react/19/replace-use-form-state
npx codemod@latest react/prop-types-typescript

# TypeScript types
npx types-react-codemod@latest preset-19 ./src

Imports (Best Practice)

// Named imports (recommended)
import { useState, useEffect, useRef, use } from 'react';
import { createRoot } from 'react-dom/client';
import { useFormStatus } from 'react-dom';

// Default import still works but named preferred
import React from 'react'; // Works but not recommended

Error Handling Changes

// React 19 error handling options
const root = createRoot(container, {
  onUncaughtError: (error, errorInfo) => {
    // Errors not caught by Error Boundary
    console.error('Uncaught:', error, errorInfo.componentStack);
  },
  onCaughtError: (error, errorInfo) => {
    // Errors caught by Error Boundary
    reportToAnalytics(error);
  },
  onRecoverableError: (error, errorInfo) => {
    // Errors React recovered from automatically
    console.warn('Recovered:', error);
  }
});

See [references/suspense-streaming.md](./references/suspense-streaming.md) for Suspense patterns and error boundaries.

React 19.2+ Features

Activity Component (19.2)

Hide/show UI while preserving state (like background tabs):

import { Activity } from 'react';

// State preserved when hidden, Effects cleaned up

  

useEffectEvent Hook (19.2)

Extract non-reactive logic from Effects without adding dependencies:

import { useEffect, useEffectEvent } from 'react';

function Chat({ roomId, theme }) {
  // Reads theme without making it a dependency
  const onConnected = useEffectEvent(() => {
    showNotification(`Connected!`, theme);
  });

  useEffect(() => {
    const conn = connect(roomId);
    conn.on('connected', onConnected);
    return () => conn.disconnect();
  }, [roomId]); // theme NOT in deps - won't reconnect on theme change
}

See [references/react-19-2-features.md](./references/react-19-2-features.md) for complete 19.1+ and 19.2 features.

Reference Documentation

| Document | Content | |----------|---------| | [paradigm-shifts.md](./references/paradigm-shifts.md) | Mental model changes - how to think in React 19 | | [anti-patterns.md](./references/anti-patterns.md) | What to stop doing - outdated patterns | | [react-19-2-features.md](./references/react-19-2-features.md) | React 19.1+ and 19.2 features (Activity, useEffectEvent) | | [new-hooks.md](./references/new-hooks.md) | Complete API for 19.0 hooks | | [server-components.md](./references/server-components.md) | RSC, Server Actions, directives | | [suspense-streaming.md](./references/suspense-streaming.md) | Suspense, streaming, error handling | | [react-compiler.md](./references/react-compiler.md) | Automatic memoization details | | [deprecations.md](./references/deprecations.md) | Removed APIs with migration guides | | [typescript-changes.md](./references/typescript-changes.md) | Type changes and codemods |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.