Claude Skills
CollectionsCompareWorkflowsNominate
Sign inSign up
© 2026 Curated Agent Skills·Learn more about Agent Skills
Back to repository

jotai-react-mastery

verified

JotaiとReact Suspense/Transitionを組み合わせたモダンな状態管理・非同期処理のベストプラクティス集。uhyo氏の「jotaiによるReact再入門」に基づく。

View on GitHub

Marketplace

kazuph-dotfiles

kazuph/dotfiles

Plugin

kazuph-dotfiles

development

Repository

kazuph/dotfiles
15stars

plugins/kazuph-dotfiles/skills/jotai-react-mastery/SKILL.md

Last Verified

February 1, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/kazuph/dotfiles/blob/main/plugins/kazuph-dotfiles/skills/jotai-react-mastery/SKILL.md -a claude-code --skill jotai-react-mastery

Installation paths:

Claude
.claude/skills/jotai-react-mastery/
Powered by add-skill CLI

Instructions

# Jotai React Mastery Skill

## 概要
Jotaiを用いたReactアプリケーション設計、特にSuspense、Concurrent features(Transition)、非同期処理、エラーハンドリングに関するベストプラクティスを提供するスキルです。
「jotaiによるReact再入門」の内容をベースに、宣言的UIの原則に従った実装パターンを提示します。

## 利用シーン
- Jotaiを用いた状態管理の設計時
- React Suspenseを利用した非同期データ取得の実装時
- `useTransition` を用いたUX改善(ちらつき防止、ペンディング表示)
- 非同期処理のエラーハンドリングとリトライ機構の実装
- `jotai-eager` を用いたパフォーマンス最適化

## ベストプラクティス & パターン

### 1. Jotaiの基本原則
- **定義と利用の分離**: `atom`でステートを定義し、`useAtom`で利用する。`useState`の役割を分割・拡張する。
- **派生atomによるカプセル化**: 生のatom(Primitive Atom)を隠蔽し、読み取り専用またはアクション用(書き込み専用)の派生atom(Derived Atom)のみを公開することで、意図しないステート変更を防ぐ。
- **最小限のAPI**: 複雑な操作はカスタムフックではなく、書き込み可能な派生atom(Action Atom)として実装する。引数を取る書き込み関数を活用する。

### 2. Suspenseと非同期処理 (Render-as-You-Fetch)
Suspenseを正しく動作させるため、Promiseはコンポーネント内(useEffectやuseMemo内)ではなく、**コンポーネントの外(Atom)**で管理する。

#### 基本パターン
```ts
// コンポーネント外でPromiseを保持する
const userAtom = atom(async () => {
  const user = await fetchUser();
  return user;
});

// コンポーネント内
const UserProfile = () => {
  // atomの値がPromiseの場合、解決するまで自動的にサスペンドする
  const user = useAtomValue(userAtom); 
  return <div>{user.name}</div>;
};
```

#### パラメータ付きクエリ
IDごとのデータ取得には以下の2パターンを使い分ける。

1. **パラメータ依存atom**(単一のパラメータのみ扱う場合)
   ```ts
   const userIdAtom = atom<string | null>(null);
   const userAtom = atom(async (get) => {
     const id = get(userIdAtom);
     if (!id) return null;
     return fetchUser(id);
   });
   ```

2. **Atom Family**(複数のパラメータを同時に扱う、キャッシュが必要な場合)
   ```ts
   import { atomFamily } from 'jotai/utils';

   const userAtomFamily = atomFamily((id: string) =>
     atom(async () => fetchUser(id))
   );

   const UserProfile = ({ id }) => {
     const user = useAtomValue(userAtomFamily(id));
     // ...
   };
   ```

### 3. 再読み込みとUIバージョニング
データの再取得(Refetch)は「手続き的な再実行」ではなく、「UIバージョン(キー)の更新によるステートの再評価」として実装する。これは「データ取得もUIの計算の一部」という宣言的UIの思想に基づく。

#### createReloadableAtom パターン
```ts
import { atom, type Getter } from "jotai";

function createReloadableAtom<T>(getter: (get: Getter) => T) {
  const refetchKeyAtom = at

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
4454 chars