# Hooks API

このセクションでは、ライブラリ内で利用可能なカスタム React Hook の詳細なリファレンスを提供します。これらのフックは、ステートフルなロジックをカプセル化して再利用するように設計されており、Blocklet 環境内での一般的なタスクやインタラクションを簡素化します。

## useComponentInstalled

このフックは、指定された1つ以上のオプションコンポーネント（DID によって識別される）がインストールされているかどうかをチェックします。これは、他の Blocklet を依存関係として利用する機能を実装するために不可欠です。このフックは、インストールのステータスと、必要に応じてユーザーにインストールを促すために必要な URL を提供します。

### パラメータ

このフックは、以下のプロパティを持つ単一のオブジェクトを受け入れます：

<x-field-group>
  <x-field data-name="did" data-type="string | string[]" data-required="true">
    <x-field-desc markdown>チェックするコンポーネントの分散型識別子（DID）または DID の配列。単一の文字列には `;;` で区切られた複数の DID を含めることができます。</x-field-desc>
  </x-field>
  <x-field data-name="onInstalled" data-type="function" data-required="false">
    <x-field-desc markdown>指定されたすべてのコンポーネントがすでにインストールされている場合にトリガーされるオプションのコールバック関数。</x-field-desc>
  </x-field>
  <x-field data-name="onError" data-type="function" data-required="false">
    <x-field-desc markdown>指定された1つ以上のコンポーネントがインストールされていない場合にトリガーされるオプションのコールバック関数。</x-field-desc>
  </x-field>
</x-field-group>

### 戻り値

インストールの状態と関連データを含むオブジェクトを返します：

<x-field-group>
  <x-field data-name="optComponents" data-type="array">
    <x-field-desc markdown>インストールされていないコンポーネントオブジェクトの配列。各オブジェクトには `meta.did`、`storeUrl`、`installUrl` などのメタデータが含まれます。</x-field-desc>
  </x-field>
  <x-field data-name="installed" data-type="boolean">
    <x-field-desc markdown>指定されたすべてのコンポーネントがインストールされ、`blocklet.yml` で定義されている場合は `true`、そうでない場合は `false` となるブール値。</x-field-desc>
  </x-field>
  <x-field data-name="installStatus" data-type="object">
    <x-field-desc markdown>キーがコンポーネントの DID で、値が現在のインストールステータス（例: 'waiting', 'installing'）であるオブジェクト。この状態は `window.postMessage` イベントを介して更新されます。</x-field-desc>
  </x-field>
  <x-field data-name="setInstallStatus" data-type="function">
    <x-field-desc markdown>`installStatus` オブジェクトを手動で更新するためのステートセッター関数。</x-field-desc>
  </x-field>
  <x-field data-name="definedInBlockletYML" data-type="boolean">
    <x-field-desc markdown>コンポーネントが blocklet の設定（`blocklet.yml`）で定義されているかどうかを示すブール値。</x-field-desc>
  </x-field>
</x-field-group>

### 使用例

以下の例は、依存関係が欠落している場合に `useComponentInstalled` を使用して、機能または `ComponentInstaller` コンポーネントを条件付きでレンダリングする方法を示しています。

```javascript "ComponentFeature.js" icon=logos:javascript
import React from 'react';
import { useComponentInstalled, ComponentInstaller } from '@blocklet/ui-react';

const REQUIRED_DID = 'z8ia24z55nve2TSF5m1aZ5322d9f48a43D4a'; // DID の例

function ComponentFeature() {
  const { installed, optComponents } = useComponentInstalled({ did: REQUIRED_DID });

  if (!installed) {
    // コンポーネントが存在しない場合は、インストーラー UI をレンダリングします
    return <ComponentInstaller components={optComponents} />;
  }

  // インストールされたコンポーネントに依存する機能をレンダリングします
  return (
    <div>
      <h2>My Feature</h2>
      <p>This feature requires the component with DID: {REQUIRED_DID}</p>
      {/* ... 機能の実装 ... */}
    </div>
  );
}

export default ComponentFeature;
```

## useFollow

このフックは、現在認証されているユーザーと、その DID によって指定された別のユーザーとの間のフォロー関係を管理します。フォローおよびアンフォローのための API 呼び出しを処理し、現在のフォロー状況を提供します。

### パラメータ

<x-field-group>
  <x-field data-name="userDid" data-type="string" data-required="true">
    <x-field-desc markdown>フォロー状況を確認する対象のユーザープロファイルの DID。</x-field-desc>
  </x-field>
  <x-field data-name="t" data-type="function" data-required="true">
    <x-field-desc markdown>成功またはエラーメッセージを表示するために使用される翻訳関数（例: `react-i18next` 由来のもの）。</x-field-desc>
  </x-field>
  <x-field data-name="isMySelf" data-type="boolean" data-required="true">
    <x-field-desc markdown>`userDid` が現在ログインしているユーザーのものである場合に `true` に設定されるべきブール値。</x-field-desc>
  </x-field>
</x-field-group>

### 戻り値

以下のプロパティを持つオブジェクトを返します：

<x-field-group>
  <x-field data-name="followed" data-type="boolean">
    <x-field-desc markdown>現在のユーザーが `userDid` で指定されたユーザーをフォローしているかどうかを示します。フォローしている場合は `true`、そうでない場合は `false` です。</x-field-desc>
  </x-field>
  <x-field data-name="followUser" data-type="function">
    <x-field-desc markdown>ユーザーをフォローするために呼び出す安定した関数。API リクエストを処理し、成功時に `followed` ステートを更新します。</x-field-desc>
  </x-field>
  <x-field data-name="unfollowUser" data-type="function">
    <x-field-desc markdown>ユーザーのフォローを解除するために呼び出す安定した関数。API リクエストを処理し、成功時に `followed` ステートを更新します。</x-field-desc>
  </x-field>
</x-field-group>

### 使用例

この例では、関係ステータスに基づいて「フォロー」または「アンフォロー」アクションを表示する `FollowButton` コンポーネントを作成する方法を示します。

```javascript "FollowButton.js" icon=logos:javascript
import React from 'react';
import Button from '@mui/material/Button';
import { useTranslation } from 'react-i18next';
import { useFollow } from '@blocklet/ui-react/hooks';
import { useSession } from '@blocklet/did-connect-react';

function FollowButton({ profileDid }) {
  const { session } = useSession();
  const { t } = useTranslation();
  const isMySelf = session?.user?.did === profileDid;

  const { followed, followUser, unfollowUser } = useFollow({
    userDid: profileDid,
    t,
    isMySelf,
  });

  if (isMySelf) {
    return null; // 自身のプロフィールにはボタンを表示しない
  }

  const handleClick = () => {
    if (followed) {
      unfollowUser();
    } else {
      followUser();
    }
  };

  return (
    <Button variant="contained" onClick={handleClick}>
      {followed ? t('profile.unfollow') : t('profile.follow')}
    </Button>
  );
}

export default FollowButton;
```

## useMobile

レスポンシブコンポーネントを作成するためのシンプルなユーティリティフックです。Material-UI の `useMediaQuery` を利用して、現在のビューポートの幅が指定されたブレークポイント未満であるかどうかを判断します。

### パラメータ

<x-field-group>
  <x-field data-name="key" data-type="number | Breakpoint" data-default="'sm'" data-required="false">
    <x-field-desc markdown>Material-UI のブレークポイントキー（例: `'xs'`、`'sm'`、`'md'`）または比較対象のピクセル値。画面幅がこの値より小さい場合にフックは `true` を返します。</x-field-desc>
  </x-field>
</x-field-group>

### 戻り値

`boolean` 値を返します。ビューポートが指定されたブレークポイントより小さい場合は `true`、そうでない場合は `false` です。

### 使用例

このフックは、Material-UI の `ThemeProvider` でラップされたコンポーネントツリー内で使用する必要があります。

```javascript "ResponsiveComponent.js" icon=logos:javascript
import React from 'react';
import Typography from '@mui/material/Typography';
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { useMobile } from '@blocklet/ui-react/hooks';

// フックを使用するコンポーネント
function ResponsiveComponent() {
  const isMobile = useMobile({ key: 'md' }); // 'md' ブレークポイントに対してチェック

  return (
    <div>
      {isMobile ? (
        <Typography variant="h6">Mobile View</Typography>
      ) : (
        <Typography variant="h4">Desktop View</Typography>
      )}
      <p>Resize your browser window to see the content change.</p>
    </div>
  );
}

// コンポーネントは ThemeProvider でラップする必要があります
const theme = createTheme();

function App() {
  return (
    <ThemeProvider theme={theme}>
      <ResponsiveComponent />
    </ThemeProvider>
  );
}

export default App;
```

---

これらのフックを使用することで、最小限のボイラープレートコードで複雑な機能を効率的に実装できます。これらのフックを使用する可能性のあるコンポーネントの詳細については、[コンポーネント](./components.md) のドキュメントを参照してください。