Install
$ agentstack add skill-rohitg00-awesome-claude-code-toolkit-react-patterns ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →About
React Patterns
use() Hook (React 19)
use() reads values from Promises and Context directly in render. Unlike other hooks, it can be called inside conditionals and loops.
import { use } from 'react';
function UserProfile({ userPromise }: { userPromise: Promise }) {
const user = use(userPromise);
return {user.name};
}
function ThemeButton() {
const theme = use(ThemeContext);
return Click;
}
Wrap components that use use() with a Promise in a `` boundary.
Server Components
// app/users/page.tsx - Server Component (default, no directive needed)
import { UserList } from './UserList';
export default async function UsersPage() {
const users = await fetch('https://api.example.com/users', {
next: { revalidate: 60 },
}).then(r => r.json());
return ;
}
// app/users/UserList.tsx - Still a Server Component
export function UserList({ users }: { users: User[] }) {
return (
{users.map(u => (
{u.name}
))}
);
}
Push 'use client' as deep as possible. Only leaves that need interactivity should be Client Components.
Server Actions
// app/actions.ts
'use server';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
export async function createPost(formData: FormData) {
const title = formData.get('title') as string;
const body = formData.get('body') as string;
await db.insert(posts).values({ title, body });
revalidatePath('/posts');
redirect('/posts');
}
// app/posts/new/page.tsx
import { createPost } from '../actions';
export default function NewPostPage() {
return (
Create
);
}
useActionState (React 19)
'use client';
import { useActionState } from 'react';
import { createUser } from './actions';
function SignupForm() {
const [state, formAction, isPending] = useActionState(createUser, {
errors: {},
message: '',
});
return (
{state.errors.email && {state.errors.email}}
{isPending ? 'Creating...' : 'Sign Up'}
{state.message && {state.message}}
);
}
useOptimistic (React 19)
'use client';
import { useOptimistic } from 'react';
import { likePost } from './actions';
function LikeButton({ count, postId }: { count: number; postId: string }) {
const [optimisticCount, addOptimistic] = useOptimistic(count);
async function handleLike() {
addOptimistic(prev => prev + 1);
await likePost(postId);
}
return (
{optimisticCount} Likes
);
}
Suspense Boundaries
import { Suspense } from 'react';
function Dashboard() {
return (
}>
}>
}>
);
}
Place Suspense boundaries around independent data-fetching units. Avoid wrapping the entire page in a single boundary (defeats the purpose of streaming).
Error Boundaries
'use client';
import { Component, type ReactNode } from 'react';
class ErrorBoundary extends Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
reportError(error, info.componentStack);
}
render() {
if (this.state.hasError) return this.props.fallback;
return this.props.children;
}
}
Or use Next.js error.tsx convention for route-level error handling.
Custom Hooks
function useDebounce(value: T, delay: number): T {
const [debounced, setDebounced] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebounced(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debounced;
}
function useLocalStorage(key: string, initial: T) {
const [value, setValue] = useState(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initial;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}
Rules for custom hooks:
- Prefix with
use - Extract when logic is shared between 2+ components
- Keep hooks focused on a single concern
- Return tuples
[value, setter]or objects{ data, error, loading }
Compound Components
function Tabs({ children }: { children: ReactNode }) {
const [active, setActive] = useState(0);
return (
{children}
);
}
Tabs.Tab = function Tab({ index, children }: { index: number; children: ReactNode }) {
const { active, setActive } = use(TabsContext);
return (
setActive(index)}
>
{children}
);
};
Tabs.Panel = function Panel({ index, children }: { index: number; children: ReactNode }) {
const { active } = use(TabsContext);
if (active !== index) return null;
return {children};
};
// Usage
Profile
Settings
Performance Rules
- Avoid creating objects/arrays in JSX props (causes re-renders)
- Use
React.memoonly after profiling confirms unnecessary re-renders - Prefer
useMemo/useCallbackfor expensive computations or stable references passed to memoized children - Use
keyto reset component state intentionally - Colocate state: keep state as close to where it is used as possible
- Avoid prop drilling beyond 2 levels; use Context or composition instead
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: rohitg00
- Source: rohitg00/awesome-claude-code-toolkit
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.