Skillshub react-19
install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/Gentleman-Programming/Gentleman-Skills/react-19" ~/.claude/skills/comeonoliver-skillshub-react-19 && rm -rf "$T"
manifest:
skills/Gentleman-Programming/Gentleman-Skills/react-19/SKILL.mdsource content
No Manual Memoization (REQUIRED)
// ✅ React Compiler handles optimization 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 <List items={sorted} onClick={handleClick} />; } // ❌ NEVER: Manual memoization const filtered = useMemo(() => items.filter(x => x.active), [items]); const handleClick = useCallback((id) => console.log(id), []);
Imports (REQUIRED)
// ✅ ALWAYS: Named imports import { useState, useEffect, useRef } from "react"; // ❌ NEVER import React from "react"; import * as React from "react";
Server Components First
// ✅ Server Component (default) - no directive export default async function Page() { const data = await fetchData(); return <ClientComponent data={data} />; } // ✅ Client Component - only when needed "use client"; export function Interactive() { const [state, setState] = useState(false); return <button onClick={() => setState(!state)}>Toggle</button>; }
When to use "use client"
- useState, useEffect, useRef, useContext
- Event handlers (onClick, onChange)
- Browser APIs (window, localStorage)
use() Hook
import { use } from "react"; // Read promises (suspends until resolved) function Comments({ promise }) { const comments = use(promise); return comments.map(c => <div key={c.id}>{c.text}</div>); } // Conditional context (not possible with useContext!) function Theme({ showTheme }) { if (showTheme) { const theme = use(ThemeContext); return <div style={{ color: theme.primary }}>Themed</div>; } return <div>Plain</div>; }
Actions & useActionState
"use server"; async function submitForm(formData: FormData) { await saveToDatabase(formData); revalidatePath("/"); } // With pending state import { useActionState } from "react"; function Form() { const [state, action, isPending] = useActionState(submitForm, null); return ( <form action={action}> <button disabled={isPending}> {isPending ? "Saving..." : "Save"} </button> </form> ); }
ref as Prop (No forwardRef)
// ✅ React 19: ref is just a prop function Input({ ref, ...props }) { return <input ref={ref} {...props} />; } // ❌ Old way (unnecessary now) const Input = forwardRef((props, ref) => <input ref={ref} {...props} />);
Keywords
react, react 19, compiler, useMemo, useCallback, server components, use hook