with one click
react
Must always be enabled when writing/reviewing React code.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Must always be enabled when writing/reviewing React code.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Build autonomous AI agents with Claude Agent SDK. TypeScript v0.2.96 | Python v0.1.56. Covers: query(), hooks, subagents, MCP, permissions, sandbox, structured outputs, and sessions. Use when: building AI agents, configuring MCP servers, setting up permissions/hooks, using structured outputs, troubleshooting SDK errors, or working with subagents.
Xiaolai's Claude tools collection. Use when user types /xiaolai. Routes to: (1) claude-agent-sdk — Agent SDK reference for building autonomous AI agents, or (2) nlpm — Natural-Language Programming Manager for scanning, scoring, and fixing NL artifacts.
Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with elements, verify page state, diff before/after actions, take annotated screenshots, check responsive layouts, test forms and uploads, handle dialogs, and assert element states. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. Use when asked to "open in browser", "test the site", "take a screenshot", or "dogfood this". (gstack)
OpenAI Codex CLI wrapper — three modes. Code review: independent diff review via codex review with pass/fail gate. Challenge: adversarial mode that tries to break your code. Consult: ask codex anything with session continuity for follow-ups. The "200 IQ autistic developer" second opinion. Use when asked to "codex review", "codex challenge", "ask codex", "second opinion", or "consult codex". (gstack) Voice triggers (speech-to-text aliases): "code x", "code ex", "get another opinion".
记录和跟踪个人重大决策。当用户说"记决策"、"记个决策"、"决策跟踪"、"回填"、"decision",或描述一个刚做的/正在考虑的重大决策(创业/事业/财务/人生)并希望系统化记录与复盘时使用。自动四层拆解(原始信息/决策事实/假设推断/结果验证),生成 2 个文件,维护索引与行为模式库,并在记新决策时用历史教训主动拦截。
Fast headless browser for QA testing and site dogfooding. Navigate any URL, interact with elements, verify page state, diff before/after actions, take annotated screenshots, check responsive layouts, test forms and uploads, handle dialogs, and assert element states. ~100ms per command. Use when you need to test a feature, verify a deployment, dogfood a user flow, or file a bug with evidence. Use when asked to "open in browser", "test the site", "take a screenshot", or "dogfood this". (gstack)
| name | react |
| description | Must always be enabled when writing/reviewing React code. |
<core_principles>
Think harder before adding useEffect. Most scenarios have better alternatives:
<when_not_to_use_effect>
Data transformation for rendering:
// ❌ Bad: Cascading updates
const [filteredItems, setFilteredItems] = useState<Item[]>([]);
useEffect(() => {
setFilteredItems(items.filter(item => item.active));
}, [items]);
// ✅ Good: Direct computation
const filteredItems = items.filter(item => item.active);
Handling user events:
// ❌ Bad: Lost interaction context
useEffect(() => {
if (buttonClicked) {
submitForm();
}
}, [buttonClicked]);
// ✅ Good: Explicit intent
const handleSubmit = () => {
submitForm();
};
Caching expensive computations:
// ❌ Bad: Manual memoization
const [expensiveResult, setExpensiveResult] = useState<Result | null>(null);
useEffect(() => {
setExpensiveResult(computeExpensiveValue(data));
}, [data]);
// ✅ Good: useMemo
const expensiveResult = useMemo(() => computeExpensiveValue(data), [data]);
Resetting state on prop changes:
// ❌ Bad: Manual synchronization
useEffect(() => {
setLocalState(defaultValue);
}, [userId]);
// ✅ Good: Key-based reset
<Profile key={userId} userId={userId} />
</when_not_to_use_effect>
<legitimate_use_cases>
Only use Effects for:
Pattern for data fetching (if not using query client):
useEffect(() => {
let ignore = false;
async function fetchData() {
const result = await api.getData();
if (!ignore) {
setData(result);
}
}
fetchData();
return () => { ignore = true; }; // Cleanup to prevent race conditions
}, [dependency]);
</legitimate_use_cases> </core_principles>
<component_definition>
Always use FC type annotation:
import { FC, PropsWithChildren } from 'react';
// For components without children
type ButtonProps {
label: string;
onClick: () => void;
}
const Button: FC<ButtonProps> = ({ label, onClick }) => {
return <button onClick={onClick}>{label}</button>;
};
// For components that accept children
type CardProps {
title: string;
}
const Card: FC<PropsWithChildren<CardProps>> = ({ title, children }) => {
return (
<div>
<h2>{title}</h2>
<div>{children}</div>
</div>
);
};
Never use function declaration syntax:
// ❌ Bad: Avoid this style
function MyComponent(props: Props) {
return <div />;
}
</component_definition>
<api_requests>
Never use fetch directly in components. Always use the project's query client.
<detection_workflow>
Check project dependencies in package.json:
@apollo/client → Use Apollo Client hooks@tanstack/react-query → Use Tanstack Query hooksswr → Use SWR hooksSearch for existing usage patterns:
useQuery, useMutation, useSWR, useApolloClient in codebaseApply appropriate client:
<apollo_client> Apollo Client (GraphQL):
import { useQuery, useMutation, gql } from '@apollo/client';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
const UserProfile: FC<{ userId: string }> = ({ userId }) => {
const { data, loading, error } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <Spinner />;
if (error) return <ErrorMessage error={error} />;
return <div>{data.user.name}</div>;
};
// Mutations
const UPDATE_USER = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, name: $name) {
id
name
}
}
`;
const EditForm: FC = () => {
const [updateUser, { loading }] = useMutation(UPDATE_USER);
const handleSubmit = async (values: FormValues) => {
await updateUser({ variables: { id: values.id, name: values.name } });
};
return <form onSubmit={handleSubmit}>...</form>;
};
</apollo_client>
<tanstack_query> Tanstack Query (REST):
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
const UserProfile: FC<{ userId: string }> = ({ userId }) => {
const { data, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => api.getUser(userId),
});
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage error={error} />;
return <div>{data.name}</div>;
};
// Mutations with cache invalidation
const EditForm: FC = () => {
const queryClient = useQueryClient();
const mutation = useMutation({
mutationFn: (values: FormValues) => api.updateUser(values),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['user'] });
},
});
const handleSubmit = (values: FormValues) => {
mutation.mutate(values);
};
return <form onSubmit={handleSubmit}>...</form>;
};
</tanstack_query>
**SWR**: ```tsx import useSWR from 'swr'; import useSWRMutation from 'swr/mutation';const UserProfile: FC<{ userId: string }> = ({ userId }) => {
const { data, error, isLoading } = useSWR(
/api/users/${userId},
fetcher
);
if (isLoading) return ; if (error) return ;
return
// Mutations const EditForm: FC = () => { const { trigger, isMutating } = useSWRMutation( '/api/users', updateUser );
const handleSubmit = async (values: FormValues) => { await trigger(values); };
return
...; };</swr>
</detection_workflow>
**Benefits of query clients**:
- Automatic caching and deduplication
- Loading/error state management
- Race condition handling
- Cache invalidation and refetching
- Optimistic updates support
</api_requests>
</core_principles>
<workflow>
## Implementation Workflow
1. **Before writing component**:
- Identify data dependencies and state requirements
- Think harder: Can state be derived instead of stored?
- Plan event handlers before considering Effects
2. **During implementation**:
- Define component with FC type annotation
- Calculate derived values at top level
- Use useMemo only for expensive computations
- Handle user interactions in event handlers
- Use query client hooks for API requests
3. **Effect review checklist**:
- [ ] Is this synchronizing with an external system?
- [ ] Could this be a calculated value instead?
- [ ] Should this be in an event handler?
- [ ] Am I using the right hook (useMemo, key prop)?
- [ ] If data fetching, is query client available?
4. **If Effect is necessary**:
- Document why Effect is required
- Implement proper cleanup to prevent memory leaks
- Handle race conditions for async operations
</workflow>
<anti_patterns>
## Anti-Patterns to Avoid
❌ **Chaining Effects**:
```tsx
// Bad: Effects triggering each other
useEffect(() => setB(a), [a]);
useEffect(() => setC(b), [b]);
// Good: Direct computation or single event handler
const b = computeB(a);
const c = computeC(b);
❌ Effect-based initialization:
// Bad: One-time initialization in Effect
useEffect(() => {
setData(expensiveInit());
}, []);
// Good: useState with initializer
const [data] = useState(() => expensiveInit());
❌ Direct fetch calls:
// Bad: Manual fetch in component
useEffect(() => {
fetch('/api/data').then(res => res.json()).then(setData);
}, []);
// Good: Use query client
const { data } = useQuery({ queryKey: ['data'], queryFn: fetchData });
</anti_patterns>