基于 SOC 职业分类
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/ffsshhttiikk/opencode-agents-skills --skill react命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | react |
| description | React development best practices and patterns |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"developers","category":"frameworks"} |
When creating React components, hooks, or applications.
import React, { useState, useCallback, useMemo } from 'react';
interface UserCardProps {
user: User;
onEdit?: (user: User) => void;
onDelete?: (userId: string) => void;
isSelected?: boolean;
}
export const UserCard: React.FC<UserCardProps> = ({
user,
onEdit,
onDelete,
isSelected = false,
}) => {
const [isExpanded, setIsExpanded] = useState(false);
const handleEdit = useCallback(() => {
onEdit?.(user);
}, [user, onEdit]);
const handleDelete = useCallback(() => {
onDelete?.(user.id);
}, [user.id, onDelete]);
return (
<div className={`user-card ${isSelected ? 'selected' : ''}`}>
<div className="user-header" onClick={() => setIsExpanded(!isExpanded)}>
<img src={user.avatarUrl} alt={user.name} />
<div>
<h3>{user.name}</h3>
<p>{user.email}</p>
</div>
<button onClick={handleEdit}>Edit</button>
<button onClick={handleDelete} disabled={user.isProtected}>
Delete
</button>
</div>
{isExpanded && (
<div className="user-details">
<p>Role: {user.role}</p>
<p>Created: {new Date(user.createdAt).toLocaleDateString()}</p>
)}
);
};
// Compound components
interface TabsProps {
defaultTab: string;
children: React.ReactNode;
}
export function Tabs({ defaultTab, children }: TabsProps) {
const [activeTab, setActiveTab] = useState(defaultTab);
const context = useMemo(() => ({ activeTab, setActiveTab }), [activeTab]);
return <TabsContext.Provider value={context}>{children}</TabsContext.Provider>;
}
Tabs.Tab = function Tab({ id, children }: { id: string; children: React.ReactNode }) {
const { activeTab, setActiveTab } = useContext(TabsContext);
return (
<button onClick={() => setActiveTab(id)} className={activeTab === id ? 'active' : ''}>
{children}
</button>
);
};
Tabs.Panel = function Panel({ id, children }: { id: string; children: React.ReactNode }) {
const { activeTab } = useContext(TabsContext);
return activeTab === id ? <div>{children}</div> : null;
};
import { useState, useEffect, useCallback } from 'react';
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
export function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch {
return initialValue;
}
});
const setValue = useCallback((value: T | ((val: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
(valueToStore);
..(key, .(valueToStore));
} (error) {
.(, error);
}
}, [key, storedValue]);
[storedValue, setValue] ;
}
// Use React.memo for component memoization
export const ExpensiveList = React.memo<ExpensiveListProps>(({ items, onSelect }) => {
return (
<ul>
{items.map(item => (
<ListItem key={item.id} item={item} onSelect={onSelect} />
))}
</ul>
);
}, (prevProps, nextProps) => {
// Custom comparison
return prevProps.items.length === nextProps.items.length;
});
// Use useMemo for expensive calculations
const sortedItems = useMemo(() => {
return [...items].sort((a, b) => b.score - a.score);
}, [items]);
// Use useCallback for stable function references
const handleSelect = useCallback((id: string) => {
onSelect(id);
}, [onSelect]);
// Lazy loading
const HeavyComponent = .( ());
() {
(
);
}