pitfalls-react
React component patterns, forms, accessibility, and responsive design. Use when building React components, handling forms, or ensuring accessibility. Triggers on: React component, useEffect, form validation, a11y, responsive, Error Boundary.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pitfalls-react.zip https://jpskill.com/download/17447.zip && unzip -o pitfalls-react.zip && rm pitfalls-react.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17447.zip -OutFile "$d\pitfalls-react.zip"; Expand-Archive "$d\pitfalls-react.zip" -DestinationPath $d -Force; ri "$d\pitfalls-react.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
pitfalls-react.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
pitfalls-reactフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
React の落とし穴
React 開発におけるよくある落とし穴と正しいパターンについて説明します。
どのような時に使うか
- React コンポーネントの構築
- フォームのバリデーションの実装
- エラー境界の追加
- アクセシビリティ (a11y) の確保
- レスポンシブなレイアウトの作成
- React コードのレビュー
ワークフロー
ステップ 1: コンポーネントのパターンをチェックする
ローディング/エラー状態とデータのチェックを確認します。
ステップ 2: フォームのバリデーションを確認する
Zod スキーマと適切なエラー表示を確実にします。
ステップ 3: アクセシビリティをチェックする
ARIA ラベルとキーボードナビゲーションを確認します。
コンポーネントのパターン
// ✅ ヘルパー関数は使用前に定義するか、エクスポートする
function formatPrice(price: number) { ... }
export default function Component() {
// ✅ データが存在することを確認してからアクセスする
if (!data) return <Loading />;
// ✅ 副作用のためだけに useEffect を使用する
useEffect(() => {
fetchData();
}, []);
// ✅ インタラクティブな要素に data-testid を付与する
return <button data-testid="submit-btn">Submit</button>;
}
// ❌ 間違い: レンダリング内で関数を定義する
return <button onClick={() => {
function doSomething() { } // ここで定義しない
doSomething();
}}>
// ✅ router を使用したナビゲーション、window は使用しない
import { Link, useLocation } from 'wouter';
<Link to="/dashboard">Go</Link>
// ❌ window.location.href = '/dashboard'
エラー境界
// ✅ 主要なコンポーネントをエラー境界で囲む
class ErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, info) {
logError({ error, componentStack: info.componentStack });
}
render() {
if (this.state.hasError) {
return <ErrorFallback onRetry={() => this.setState({ hasError: false })} />;
}
return this.props.children;
}
}
// ✅ グレースフルデグラデーション
function Dashboard() {
const { data, error, isLoading } = useQuery(...);
if (isLoading) return <Skeleton />;
if (error) return <ErrorCard message="Unable to load" onRetry={refetch} />;
if (!data) return <EmptyState />;
return <DashboardContent data={data} />;
}
フォームのバリデーション
// ✅ すべてのフォームに Zod スキーマを使用する
const createStrategySchema = z.object({
name: z.string().min(1, 'Name required').max(100),
type: z.enum(['cross-exchange', 'triangular']),
minProfit: z.number().positive('Must be positive'),
});
// ✅ Zod を使用した React Hook Form
const form = useForm<z.infer<typeof createStrategySchema>>({
resolver: zodResolver(createStrategySchema),
});
// ✅ エラーをインラインで表示する
{errors.name && <span className="text-red-500">{errors.name.message}</span>}
// ✅ バリデーション/送信中は送信を無効にする
<button disabled={isSubmitting || !isValid}>Submit</button>
レスポンシブなレイアウト
/* ✅ モバイルファーストのブレークポイント */
.container { padding: 1rem; }
@media (min-width: 768px) {
.container { padding: 2rem; }
}
/* ✅ タッチフレンドリーなボタンサイズ (最小 44px) */
.btn { min-height: 44px; min-width: 44px; }
/* ✅ モバイルでのデータテーブルの水平スクロール */
.table-container { overflow-x: auto; }
アクセシビリティ (a11y)
// ✅ セマンティック HTML
<nav>...</nav>
<main>...</main>
<button>Click me</button> // <div onClick> ではない
// ✅ ARIA ラベル
<button aria-label="Close dialog">×</button>
// ✅ キーボードナビゲーション
<button onKeyDown={(e) => e.key === 'Enter' && handleClick()}>
// ✅ フォーカスインジケーター
button:focus { outline: 2px solid blue; outline-offset: 2px; }
簡単なチェックリスト
- [ ] ローディング/エラー状態が処理されている
- [ ] インタラクティブな要素に data-testid が付与されている
- [ ] window.location ではなく、router の Link を使用している
- [ ] ヘルパー関数は使用前に定義されている
- [ ] 主要なコンポーネントにエラー境界がある
- [ ] タッチターゲットが 44px 以上である
- [ ] アイコンボタンに ARIA ラベルが付与されている
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
React Pitfalls
Common pitfalls and correct patterns for React development.
When to Use
- Building React components
- Implementing form validation
- Adding error boundaries
- Ensuring accessibility (a11y)
- Creating responsive layouts
- Reviewing React code
Workflow
Step 1: Check Component Patterns
Verify loading/error states and data checks.
Step 2: Verify Form Validation
Ensure Zod schemas and proper error display.
Step 3: Check Accessibility
Verify ARIA labels and keyboard navigation.
Component Patterns
// ✅ Define helpers before use or as exports
function formatPrice(price: number) { ... }
export default function Component() {
// ✅ Check data exists before accessing
if (!data) return <Loading />;
// ✅ useEffect for side effects only
useEffect(() => {
fetchData();
}, []);
// ✅ data-testid on interactive elements
return <button data-testid="submit-btn">Submit</button>;
}
// ❌ WRONG: Defining function in render
return <button onClick={() => {
function doSomething() { } // Don't define here
doSomething();
}}>
// ✅ Navigation with router, not window
import { Link, useLocation } from 'wouter';
<Link to="/dashboard">Go</Link>
// ❌ window.location.href = '/dashboard'
Error Boundary
// ✅ Wrap major components in error boundaries
class ErrorBoundary extends React.Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, info) {
logError({ error, componentStack: info.componentStack });
}
render() {
if (this.state.hasError) {
return <ErrorFallback onRetry={() => this.setState({ hasError: false })} />;
}
return this.props.children;
}
}
// ✅ Graceful degradation
function Dashboard() {
const { data, error, isLoading } = useQuery(...);
if (isLoading) return <Skeleton />;
if (error) return <ErrorCard message="Unable to load" onRetry={refetch} />;
if (!data) return <EmptyState />;
return <DashboardContent data={data} />;
}
Form Validation
// ✅ Zod schemas for all forms
const createStrategySchema = z.object({
name: z.string().min(1, 'Name required').max(100),
type: z.enum(['cross-exchange', 'triangular']),
minProfit: z.number().positive('Must be positive'),
});
// ✅ React Hook Form with Zod
const form = useForm<z.infer<typeof createStrategySchema>>({
resolver: zodResolver(createStrategySchema),
});
// ✅ Show errors inline
{errors.name && <span className="text-red-500">{errors.name.message}</span>}
// ✅ Disable submit while validating/submitting
<button disabled={isSubmitting || !isValid}>Submit</button>
Responsive Layout
/* ✅ Mobile-first breakpoints */
.container { padding: 1rem; }
@media (min-width: 768px) {
.container { padding: 2rem; }
}
/* ✅ Touch-friendly button sizes (min 44px) */
.btn { min-height: 44px; min-width: 44px; }
/* ✅ Horizontal scroll for data tables on mobile */
.table-container { overflow-x: auto; }
Accessibility (a11y)
// ✅ Semantic HTML
<nav>...</nav>
<main>...</main>
<button>Click me</button> // Not <div onClick>
// ✅ ARIA labels
<button aria-label="Close dialog">×</button>
// ✅ Keyboard navigation
<button onKeyDown={(e) => e.key === 'Enter' && handleClick()}>
// ✅ Focus indicators
button:focus { outline: 2px solid blue; outline-offset: 2px; }
Quick Checklist
- [ ] Loading/error states handled
- [ ] data-testid on interactive elements
- [ ] Using router Link, not window.location
- [ ] Helper functions defined before use
- [ ] Error boundaries on major components
- [ ] Touch targets ≥ 44px
- [ ] ARIA labels on icon buttons