メインコンテンツまでスキップ

React SDK

React SDK

SquidとReactを統合するためのライブラリ。

Features

  • Squid Clientのcollections、documents、queriesにアクセスするためのHooks。
  • ReactコンポーネントのどこからでもSquid ClientにアクセスできるProvider。

Getting started

Requirements

このSDKは最低でもReact 16.11が必要です。

Installation

NPMを使用してSquid React SDKをインストールします:

npm install @squidcloud/react

Configure Squid

  1. Squid Consoleにアクセスし、Create applicationをクリックしてアプリケーションを作成します。

  2. 新しいアプリケーションのoverviewタブからApplication IDをコピーします。

  3. Reactアプリケーションに以下のproviderを追加します:

// main.tsx

import { SquidContextProvider } from '@squidcloud/react';
import ReactDOM from 'react-dom/client';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
<SquidContextProvider
options={{
appId: '<SQUID_CLOUD_APP_ID>',
region: '<SQUID_CLOUD_REGION>',
}}
>
<App />
</SquidContextProvider>
);

注意: 環境管理に.envファイルを使用している場合は、appIdregionを好みのenvarsに設定してください:

// main.tsx

<SquidContextProvider
options={{
appId: process.env.SQUID_CLOUD_APP_ID,
region: process.env.SQUID_CLOUD_REGION,
}}
>

Hooks

アプリケーションをSquidContextProviderでラップすることで、アプリにSquidインスタンスへのアクセスが提供されます。このインスタンスに直接アクセスするには、useSquid hookを使用してください。

function App() {
const squid = useSquid();

const foo = () => {
squid.executeFunction('foo');
};

return <button onClick={foo}>Foo</button>;
}

しかし、collections、queries、documentsにアクセスするための追加のhooksも用意されています。

useCollection

useCollection hookは、squid.collection(...)のラッパーです。これにより、squidへの参照がなくてもcollectionにアクセスできます。一度collectionを取得すれば、そのcollectionを使用してqueriesを作成したりdocumentsを管理することができます。

const collection = useCollection<User>('users');

const query = collection.query().eq('name', 'John Doe');
const doc = collection.doc('user-id');

useQuery

queryが作成されたら、useQuery hookを使用して実行し、必要に応じて結果にsubscribeできます。

このhookは以下のプロパティを含むオブジェクトを返します:

  • loading: queryからデータが返されたかどうか。
  • data: クエリ結果の配列。これは、document references、document data、join query resultsなど、hookに渡されるqueryのタイプによって異なります。
  • error: クエリの実行中にエラーが発生した場合のエラーオブジェクト。
function App() {
const collection = useCollection<User>('users');

/**
* The list of docs will be streamed to the client and will be
* kept up-to-date.
*/
const { docs } = useQuery(collection.query().gt('age', 18), {
subscribe: true,
initialData: [],
});

return (
<ul>
{docs.map((d) => (
<li key={d.refId}>{d.data.age}</li>
))}
</ul>
);
}

subscribeオプションがtrueに設定されている場合、データはクライアントにストリーミングされ、新しいアップデートが受信されるとコンポーネントは自動的に再レンダリングされます。subscribeがfalseの場合、クエリの初期データが取得されますが、変更はストリーミングされません。

オプションで、最初の結果が読み込まれるまで返されるinitialDataオプションを使用することもできます。

usePagination

usePagination hookは、クエリ結果のページネーションに使用されます。ページネーションを処理し、データを変更に合わせて最新の状態に保つためのインターフェースを提供します。Squidのページネーションの詳細については、pagination documentation をご覧ください。

このhookは以下のプロパティを含むオブジェクトを返します:

  • loading: 現在データが読み込まれている、またはページネーション中かどうか。
  • data: ページネーションされた結果の配列。これは、document references、document data、join query resultsなど、hookに渡されるクエリのタイプによって異なります。
  • hasNext: 現在のページの後にさらに結果が利用可能かどうかを示すboolean。
  • hasPrev: 現在のページの前にさらに結果が利用可能かどうかを示すboolean。
  • next: 次のページの結果を読み込むための関数(hasNextがtrueの場合のみ有効)。
  • prev: 前のページの結果を読み込むための関数(hasPrevがtrueの場合のみ有効)。
function App() {
const collection = useCollection<User>('users');

/**
* Paginate through the list of users.
* The list of docs will be streamed to the client and will be kept up-to-date.
*/
const { docs, loading, hasNext, hasPrev, next, prev } = usePagination(
collection.query().eq('age', 30).sortBy('name'),
{ subscribe: true, pageSize: 10 } /* PaginationOptions */,
[30] // deps
);

if (loading) {
return <div>Loading...</div>;
}

return (
<div>
<ul>
{docs.map((d) => (
<li key={d.refId}>{d.data.name}</li>
))}
</ul>
<button onClick={prev} disabled={!hasPrev}>
Previous
</button>
<button onClick={next} disabled={!hasNext}>
Next
</button>
</div>
);
}

subscribeオプションがtrueに設定されている場合、データはクライアントにストリーミングされ、新しいアップデートが受信されるとコンポーネントは自動的に再レンダリングされます。ページの最初と最後の項目の間に新しいデータが追加された場合、ページは自動的に更新され、新しいデータが表示され、常にpageSizeの項目のみが表示されることが保証されます。

ページネーションを使用するには、クエリでsortByを指定する必要があります。

オプションで、deps配列を受け取ることもできます。deps配列が変更されると、新しいページネーションクエリが作成されます。

useDoc

useDoc hookは類似の機能を提供しますが、クエリの購読の代わりに特定のdocumentのアップデートを購読します。

このhookは以下のプロパティを含むオブジェクトを返します:

  • loading: document queryからデータが返されたかどうか。
  • data: document data。データが受信されていなかったり、documentが削除された場合はundefinedになります。
  • error: documentのクエリ中にエラーが発生した場合のエラーオブジェクト。
// App.tsx

function App() {
const collection = useCollection<User>('users');
const doc = collection.doc('user-id');

/**
* Changes to the doc will be streamed to the client and it will be
* kept up-to-date.
*/
const { data } = useDoc(doc);

return <span>{data.foo}</span>;
}

useDocs

useDocs hookは複数のdocument referenceのアップデートを提供します。

このhookは以下のプロパティを含むオブジェクトを返します:

  • loading: すべてのdocumentクエリでデータが返されたかどうか。
  • data: document dataの配列。各要素は、データが受信されていなかったり、documentが削除された場合undefinedになる可能性があります。
  • error: いずれかのdocumentクエリの実行中にエラーが発生した場合のエラーオブジェクト。
// App.tsx

function App() {
const collection = useCollection<User>('users');
const docs = [collection.doc('my-id-1'), collection.doc('my-id-2')];

/**
* Changes to the documents will be streamed to the client and they will be
* kept up-to-date.
*/
const { data } = useDocs(docs);

return (
<ul>
<li>{data[0].foo}</li>
<li>{data[1].foo}</li>
</ul>
);
}

Async Hooks

Squid Client SDKはPromisesやObservablesを使用していますが、これらの非同期アップデートをReactコンポーネントでサポートするためにはいくつかの工夫が必要です。

すべてのSquid Client SDKの機能がReactに容易に統合できるように、SquidはusePromiseuseObservable hooksを公開しています。これらのhooksを使用すると、Reactコンポーネント内でsquidインスタンス上の非同期関数を直接利用できます。

useObservable

useObservable hookは、Observable<T>を返す関数を受け取り、observableに購読してコンポーネント内でアップデートを受け取ることを可能にします。以下のプロパティを含むオブジェクトを返します:

  • loading: observableから値が受信されたかどうか。
  • data: observableから受信した最新のデータ。
  • error: observableでエラーが発生した場合のエラーオブジェクト。
  • complete: observableが完了したかどうか。
function App() {
const [bar, setBar] = useState('bar');
const squid = useSquid();

const { loading, data, error, complete } = useObservable(
() => {
return squid.collection<User>('users').query().gt('foo', bar).snapshots();
},
{ initialData: [] },
[bar] // deps
);
}

オプションで、initialDataオプション(デフォルトはnull)とdeps配列を受け取ることもできます。deps配列が変更されると、現在のobservableは購読解除され、新しい購読が作成されます。上記の例では、クエリのwhere条件がbar変数に依存しているため、barを依存関係として渡す必要があります。

depsが変更されるたびに、新しく作成されたobservableから値が発行されるまでloadingはtrueにリセットされます。

usePromise

usePromise hookはuseObservableと類似していますが、Promise<T>を返す関数を受け取ります。hookが直接promiseではなく関数を受け取る理由は、コンポーネントがマウントされるまでpromiseの実行を開始しないようにするためです。

  • loading: promiseが解決または拒否されたかどうか。
  • data: promiseによって解決されたデータ。
  • error: promiseが拒否された場合のエラーオブジェクト。
function App() {
const [bar, setBar] = useState('bar');
const squid = useSquid();

const { loading, data, error } = usePromise(
() => {
return squid.collection<User>('users').query().gt('foo', bar).snapshot();
},
{ initialData: [] },
[bar] // deps
);
}

このhookはまた、initialDataオプション(デフォルトはnull)とdeps配列を受け取ることができます。depsが変更されるたびに、進行中のpromiseの結果は無視され、新しいpromiseが作成されます。上記の例では、bar変数が変更されるたびに新しいpromiseが作成されます。

Feature Hooks

上記のhooksに加えて、Squid React SDKは一般的なSquidの使用ケースを簡素化するために設計されたhooksも提供しています。

useAiChatbot

useAiChatbot hookは、AI Chatbotをラップし、質問の送信やチャット履歴へのアクセスを容易にします。以下のように使用できます:

const { chat, history, data, loading, complete, error } = useAiChatbot('integration-id', 'profile-id');

そして、以下のものを返します:

  • chat: AIエージェントへのプロンプト(文字列)を受け取る関数。
  • history: メッセージの配列。各メッセージはidmessage、およびtypeaiまたはuser)を持ち、AIエージェントからのアクティブなレスポンスを含みます。
  • data: 現在のレスポンス(チャットが進行中の場合)。
  • loading: 現在のプロンプトに対するレスポンスを待機中かどうか。
  • complete: 現在のレスポンスが完了しているかどうか。
  • error: 現在のプロンプトに対してエラーが返された場合に設定されます。
const Chat = () => {
const [value, setValue] = useState('');
const { history, chat, complete } = useAiChatbot('integration-id', 'profile-id');

const handleClick = () => {
chat(value);
};

return (
<>
<input onChange={(e) => setValue(e.target.value)} value={value} />
<button onClick={handleClick} disabled={!complete}>
Chat
</button>
{history.map(({ id, message, type }) => (
<span key={id}>
{type}: {message}
</span>
))}
</>
);
};