--- title: 'SDK (React)' description: 'Use the bknd SDK for React' --- For all SDK options targeting React, you always have 2 options: 1. use simple hooks which are solely based on the [API](/sdk) 2. use the query hook that makes wraps the API in [SWR](https://swr.vercel.app/) To use the simple hook that returns the Api, you can use: ```tsx import { useApi } from "bknd/client"; export default function App() { const api = useApi(); // ... } ``` ## `useApiQuery([selector], [options])` This hook wraps the API class in an SWR hook for convenience. You can use any API endpoint supported, like so: ```tsx import { useApiQuery } from "bknd/client"; export default function App() { const { data, ...swr } = useApiQuery((api) => api.data.readMany("comments")); if (swr.error) return
Error
if (swr.isLoading) return
Loading...
return
{JSON.stringify(data, null, 2)}
} ``` ### Props * `selector: (api: Api) => FetchPromise` The first parameter is a selector function that provides an Api instance and expects an endpoint function to be returned. * `options`: optional object that inherits from `SWRConfiguration` ```ts type Options = SWRConfiguration & { enabled?: boolean; refine?: (data: Data) => Data | any; } ``` * `enabled`: Determines whether this hook should trigger a fetch of the data or not. * `refine`: Optional refinement that is called after a response from the API has been received. Useful to omit irrelevant data from the response (see example below). ### Using mutations To query and mutate data using this hook, you can leverage the parameters returned. In the following example we'll also use a `refine` function as well as `revalidateOnFocus` (option from `SWRConfiguration`) so that our data keeps updating on window focus change. ```tsx import { useState } from "react"; import { useApiQuery } from "bknd/client"; export default function App() { const [text, setText] = useState(""); const { data, api, mutate, ...q } = useApiQuery( (api) => api.data.readOne("comments", 1), { // filter to a subset of the response refine: (data) => data.data, revalidateOnFocus: true } ); const comment = data ? data : null; useEffect(() => { setText(comment?.content ?? ""); }, [comment]); if (q.error) return
Error
if (q.isLoading) return
Loading...
return (
{ e.preventDefault(); if (!comment) return; // this will automatically revalidate the query await mutate(async () => { const res = await api.data.updateOne("comments", comment.id, { content: text }); return res.data; }); return false; }} > setText(e.target.value)} />
); } ``` ## `useEntity()` This hook wraps the endpoints of `DataApi` and returns CRUD options as parameters: ```tsx import { useState } from "react", import { useEntity } from "bknd/client"; export default function App() { const [data, setData] = useState(); const { create, read, update, _delete } = useEntity("comments", 1); useEffect(() => { read().then(setData); }, []); return
{JSON.stringify(data, null, 2)}
} ``` If you only supply the entity name as string without an ID, the `read` method will fetch a list of entities instead of a single entry. ### Props Following props are available when using `useEntityQuery([entity], [id?])`: - `entity: string`: Specify the table name of the entity - `id?: number | string`: If an id given, it will fetch a single entry, otherwise a list ### Returned actions The following actions are returned from this hook: - `create: (input: object)`: Create a new entry - `read: (query: Partial = {})`: If an id was given, it returns a single item, otherwise a list - `update: (input: object, id?: number | string)`: If an id was given, the id parameter is optional. Updates the given entry partially. - `_delete: (id?: number | string)`: If an id was given, the id parameter is optional. Deletes the given entry. ## `useEntityQuery()` This hook wraps the actions from `useEntity` around `SWR`. The previous example would look like this: ```tsx import { useState } from "react", import { useEntityQuery } from "bknd/client"; export default function App() { const { data } = useEntityQuery("comments", 1); return
{JSON.stringify(data, null, 2)}
} ``` ### Using mutations All actions returned from `useEntityQuery` are conveniently wrapped around the `mutate` function, so you don't have think about this: ```tsx import { useState } from "react"; import { useEntityQuery } from "bknd/client"; export default function App() { const [text, setText] = useState(""); const { data, update, ...q } = useEntityQuery("comments", 1); const comment = data ? data : null; useEffect(() => { setText(comment?.content ?? ""); }, [comment]); if (q.error) return
Error
if (q.isLoading) return
Loading...
return (
{ e.preventDefault(); if (!comment) return; // this will automatically revalidate the query await update({ content: text }); return false; }} > setText(e.target.value)} />
); } ```