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

React SDK

Squid を React と統合するための library です。

SDK Version

Features​

  • Squid Client の collection、document、query に access するための Hooks。
  • React component 内のどこからでも Squid Client に access するための provider。

Getting started​

Requirements​

この SDK には React 16.11 以降が必要です。

Installation​

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

npm install @squidcloud/react

Squid を構成する​

  1. Squid Console に移動し、Create application をクリックして Application を作成します。

  2. 新しい Application の overview tab から Application ID をコピーします。

  3. 次の provider を React application に追加します。

// 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>
);

注記: environment management に .env file を使用している場合は、appId と region に使用する envar を設定します。

// main.tsx

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

Hooks​

application を SquidContextProvider でラップすると、app は Squid instance に access できるようになります。この instance を直接参照するには、useSquid hook を使用します。

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

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

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

さらに、collection、query、document に access するための hook もあります。

useCollection​

useCollection hook は squid.collection(...) の wrapper です。squid reference がなくても collection に access できます。collection を取得すると、collection を使用して query の作成と document の管理ができます。

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

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

useQuery​

query を作成したら、useQuery hook を使用してこれを実行し、必要に応じて result を subscribe します。

hook は以下の property を含む object を返します。

  • loading: query から data が返されたかどうか。
  • data: array としての query result。hook に渡す query type に応じて、document reference、document data、join query result などになります。
  • error: query 実行中に error が発生した場合の error object。
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 { data } = useQuery(collection.query().gt('age', 18), {
subscribe: true,
initialData: [],
});

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

subscribe option が true に設定されている場合、data は client に stream され、新しい update を受信すると component は自動的に re-render されます。subscribe が false の場合、query の initial data は fetch されますが、change は stream されません。

必要に応じて、最初の result が load されるまで返される initialData option も hook に渡せます。

usePagination​

usePagination hook は query result を paginate するために使用します。pagination を処理し、change に合わせて data を最新に保つ interface を提供します。Squid の pagination の詳細については、pagination documentationを参照してください。

hook は以下の property を含む object を返します。

  • loading: data が現在 loading または pagination 中かどうか。
  • data: array としての paginated result。hook に渡す query type に応じて、document reference、document data、join query result などになります。
  • hasNext: current page の後にさらに result があるかを示す boolean。
  • hasPrev: current page の前にさらに result があるかを示す boolean。
  • next: 次の page の result を load する function(hasNext が true の場合のみ active)。
  • prev: 前の page の result を load する function(hasPrev が true の場合のみ active)。
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 option が true に設定されている場合、data は client に stream され、新しい update を受信すると component は自動的に re-render されます。page の最初と最後の item の間に新しい data が追加された場合、pageSize item のみが表示されるよう、page は新しい data を表示するために自動的に update されます。

pagination を使用するには、query で sortBy を指定する必要があります。

必要に応じて、hook は deps array も受け取れます。deps array が change すると、新しい pagination query が作成されます。

useDoc​

useDoc hook は同様の機能を提供しますが、query を subscribe する代わりに、特定 document の update を subscribe します。

hook は以下の property を含む object を返します。

  • loading: document query から data が返されたかどうか。
  • data: document data。data をまだ受信していない場合、または document が delete された場合は undefined になることがあります。
  • error: document の query 中に error が発生した場合の error object。
// 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 の update を提供します。

hook は以下の property を含む object を返します。

  • loading: すべての document query から data が返されたかどうか。
  • data: document data の array。data をまだ受信していない場合、または document が delete された場合、array 内の element は undefined になることがあります。
  • error: いずれかの document の query 中に error が発生した場合の error object。
// 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 は Promise と Observable を使用しますが、この種の asynchronous update を React component でサポートするには追加の処理が必要です。

Squid Client SDK のすべての機能を React と簡単に統合できるよう、Squid は usePromise と useObservable hook を公開しています。 これらの hook により、React component 内で squid instance の asynchronous function を直接使用できます。

useObservable​

useObservable hook は Observable<T> を返す function を受け取ります。これにより observable を subscribe し、component 内で update を受信できます。以下の property を含む object を返します。

  • loading: observable から value を受信したかどうか。
  • data: observable から受信した最新 data。
  • error: observable で error が発生した場合の error object。
  • 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
);
}

必要に応じて、hook は initialData option(default は null)と deps array も受け取れます。deps array が change すると、current observable は unsubscribe され、新しい subscription が作成されます。上記の例では、query の where condition は bar variable に依存しています。bar の change 時に query が適切に update されるよう、dependency として渡す必要があります。

deps が change するたびに、loading は新しく作成された observable から value が emit されるまで true に reset されます。

usePromise​

usePromise hook は useObservable と同様ですが、Promise<T> を返す function を受け取ります。promise を直接ではなく function として受け取る理由は、component が mount されるまで promise の execution が開始されないようにするためです。

  • loading: promise が resolve または reject されたかどうか。
  • data: promise が resolve した data。
  • error: promise が reject された場合の error object。
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 option(default は null)と deps array も受け取れます。deps が change するたびに、実行中の promise の result は無視され、新しい promise が作成されます。上記の例では、bar variable が change するたびに新しい promise が作成されます。

Feature Hooks​

上記の hook に加え、Squid React SDK は一般的な Squid の use case を簡略化するために設計された hook も提供します。

useAiChat​

useAiChat hook は Squid AI Agent を wrap し、質問の送信と chat history への access を簡単にします。hook は次のように使用できます。

const { chat, history, data, loading, complete, error } = useAiChat('agent-id');

返される内容:

  • chat: AI agent 用の prompt(string)を受け取る function。
  • history: message の array。message には id、message、ai または user のいずれかである type が含まれ、AI agent からの active response も含みます。
  • data: current response(chat の実行中の場合)。
  • loading: current prompt の response を待機中かどうか。
  • complete: current response が完了したかどうか。
  • error -> current prompt に対する error が返された場合に設定されます。
const Chat = () => {
const [value, setValue] = useState('');
const { history, chat, complete } = useAiChat('agent-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>
))}
</>
);
};