2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるロジック再利用戦略:Hooks/Composablesの抽出、依存最小化、横断的関心事の構造化

Posted at

概要

ロジックの再利用とは「共通関数にすること」ではない。
それは**“横断的に使われる処理を、意味と責務で切り出し、依存から切り離して拡張可能にする戦略的設計”**である。

Vueの Composables、Reactの Custom Hooks は、ただの「便利関数」ではなく、UI層とロジック層を分離し、アプリを構造的に再利用可能にするための設計装置である。


1. Composables / Hooks の定義と責務

// React
function useUserLoader(id) {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch(`/api/users/${id}`).then(res => res.json()).then(setUser);
  }, [id]);
  return user;
}

// Vue
export function useUserLoader(id) {
  const user = ref(null);
  onMounted(async () => {
    user.value = await api.fetchUser(id);
  });
  return { user };
}
  • ✅ 外部から 値や関数を受け取り、副作用や状態を内部で完結
  • ✅ UIに依存せず、意味単位で再利用可能

2. 「再利用される」ではなく「再利用可能である」が設計基準

❌ UIと密結合 → 他のコンポーネントで使えない
✅ ロジックを抽象化 → UIに依存しないComposableに
export function useToggle(defaultValue = false) {
  const state = ref(defaultValue);
  const toggle = () => (state.value = !state.value);
  return { state, toggle };
}

3. 横断的関心事(Cross-cutting Concerns)の分離設計

- ローディング制御 → useLoading
- エラーハンドリング → useError
- APIフェッチ汎用化 → useFetch
- モーダル開閉 → useModal
  • ✅ どの画面にも関係する処理は 横断ユースケースとして切り出す

4. UIとの境界を明確に保つ

❌ useXxx の中で DOM に直接アクセス  
✅ UIイベントは親で受け取り、Composableには状態とロジックのみを閉じ込める
  • ✅ Composables / Hooks は ロジックレイヤーに留める
  • ✅ 表示・入力との直接操作は UI側に残す

5. Composables / Hooks の構成粒度と依存戦略

- useUser → 小さすぎて曖昧  
- useFetchUser → 責務明確
- usePaginatedUserList → 意味単位で再利用可能
  • ✅ データ・副作用・UI操作が混ざらないよう設計
  • ✅ API依存・状態依存は引数注入にすると柔軟性が高まる

6. テスト可能な構造を保つ(Pure & Injected)

export function useUserFetcher(apiClient) {
  const user = ref(null);
  const fetch = async (id) => {
    user.value = await apiClient.fetchUser(id);
  };
  return { user, fetch };
}
  • ✅ 外部依存(API)を注入可能に → テスト時はモックに置き換え
  • ✅ Composables / Hooks を プレーンなロジックレイヤーとして扱う

設計判断フロー

① この処理は他でも使えるか? → 目的単位でComposableに切り出す

② UIに依存していないか? → DOM / props に密結合していないか確認

③ 状態管理・副作用・UI操作が1ファイルに混在していないか?

④ 外部依存を内部に閉じ込めていないか? → 引数注入で柔軟化

⑤ Composable内の構造がテスト可能か? → 外部に出す責務を定義

よくあるミスと対策

❌ Composable の中でUI状態まで握ってしまう

→ ✅ 状態はロジックに限定し、UI制御は外に出す


❌ 毎回似た処理を書いてコピペ地獄に

→ ✅ useFetch系や useToggle系など汎用Composableを整備


❌ Composableが肥大化して読めなくなる

→ ✅ 1関数1責務 + 機能単位でファイル分離


結語

ロジックの再利用とは「まとめること」ではない。
それは**“意味で分け、責務で切り出し、構造として再利用可能にする設計行為”**である。

  • 状態・副作用をComposableに閉じ込め
  • UIとロジックを明確に分離し
  • 外部依存を注入構造で制御し
  • 横断的なロジックを柔軟に再利用する

JavaScriptにおけるロジック再利用戦略とは、
“破綻せず拡張可能な構造を作り出す、責任と柔軟性のデザイン”である。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?