diff --git a/.changeset/lovely-dodos-prove.md b/.changeset/lovely-dodos-prove.md
new file mode 100644
index 000000000..f10895af9
--- /dev/null
+++ b/.changeset/lovely-dodos-prove.md
@@ -0,0 +1,7 @@
+---
+"@lens-protocol/react": minor
+"@lens-protocol/react-native": minor
+"@lens-protocol/react-web": minor
+---
+
+**feat:** add React Suspense support to `useSearchPublications` hook
diff --git a/examples/web/src/discovery/UseSearchPublications.tsx b/examples/web/src/discovery/UseSearchPublications.tsx
index 5e522f40c..c3e09e676 100644
--- a/examples/web/src/discovery/UseSearchPublications.tsx
+++ b/examples/web/src/discovery/UseSearchPublications.tsx
@@ -1,8 +1,7 @@
import { LimitType, useSearchPublications } from '@lens-protocol/react-web';
-import { useState } from 'react';
+import { Suspense, startTransition, useState } from 'react';
import { PublicationCard } from '../components/cards';
-import { ErrorMessage } from '../components/error/ErrorMessage';
import { Loading } from '../components/loading/Loading';
import { useInfiniteScroll } from '../hooks/useInfiniteScroll';
@@ -11,17 +10,14 @@ type SearchResultsProps = {
};
function SearchResults({ query }: SearchResultsProps) {
- const { data, error, loading, hasMore, observeRef } = useInfiniteScroll(
+ const { data, hasMore, observeRef } = useInfiniteScroll(
useSearchPublications({
query,
limit: LimitType.Fifty,
+ suspense: true,
}),
);
- if (loading) return ;
-
- if (error) return ;
-
if (data.length === 0) {
return
No publications found
;
}
@@ -48,7 +44,9 @@ export function UseSearchPublications() {
const q = formData.get('query') as string | null;
if (q) {
- setQuery(q);
+ startTransition(() => {
+ setQuery(q);
+ });
}
};
@@ -62,7 +60,7 @@ export function UseSearchPublications() {
- {query && }
+ }>{query && }
);
}
diff --git a/packages/react/src/discovery/useSearchProfiles.ts b/packages/react/src/discovery/useSearchProfiles.ts
index 580c648d4..c7e940291 100644
--- a/packages/react/src/discovery/useSearchProfiles.ts
+++ b/packages/react/src/discovery/useSearchProfiles.ts
@@ -79,9 +79,11 @@ export function useSearchProfiles(args: UseSearchProfilesArgs): PaginatedReadRes
* suspense: true,
* });
*
- * const search = startTransition(() => {
- * setQuery('foo');
- * });
+ * const search = () => {
+ * startTransition(() => {
+ * setQuery('foo');
+ * });
+ * };
* ```
*
* @experimental This API can change without notice
diff --git a/packages/react/src/discovery/useSearchPublications.ts b/packages/react/src/discovery/useSearchPublications.ts
index 39b1d7ef0..385e2eb11 100644
--- a/packages/react/src/discovery/useSearchPublications.ts
+++ b/packages/react/src/discovery/useSearchPublications.ts
@@ -1,23 +1,37 @@
import {
PrimaryPublication,
PublicationSearchRequest,
- useSearchPublications as useBaseSearchPublications,
+ PublicationSearchWhere,
+ SearchPublicationsDocument,
} from '@lens-protocol/api-bindings';
import { useLensApolloClient } from '../helpers/arguments';
-import { PaginatedArgs, PaginatedReadResult, usePaginatedReadResult } from '../helpers/reads';
+import { PaginatedArgs, PaginatedReadResult } from '../helpers/reads';
+import {
+ SuspendablePaginatedResult,
+ SuspenseEnabled,
+ SuspensePaginatedResult,
+ useSuspendablePaginatedQuery,
+} from '../helpers/suspense';
import { useFragmentVariables } from '../helpers/variables';
+/**
+ * {@link useSearchPublications} hook arguments
+ */
export type UseSearchPublicationsArgs = PaginatedArgs;
+export type { PublicationSearchRequest, PublicationSearchWhere };
+
/**
- * Search for publications based on a defined criteria
+ * {@link useSearchPublications} hook arguments with Suspense support
*
- * @category Discovery
- * @group Hooks
- * @param args - {@link UseSearchPublicationsArgs}
+ * @experimental This API can change without notice
+ */
+export type UseSuspenseSearchPublicationsArgs = SuspenseEnabled;
+
+/**
+ * Search for publications based on a defined criteria
*
- * @example
* Search for publications with content that contains "foo"
* ```tsx
* import { useSearchPublications } from '@lens-protocol/react';
@@ -41,7 +55,6 @@ export type UseSearchPublicationsArgs = PaginatedArgs;
* }
* ```
*
- * @example
* Search for audio post publications with content that matches a query
* ```tsx
* import { useSearchPublications } from '@lens-protocol/react';
@@ -72,22 +85,71 @@ export type UseSearchPublicationsArgs = PaginatedArgs;
* );
* }
* ```
+ *
+ * @category Discovery
+ * @group Hooks
*/
+export function useSearchPublications(
+ args: UseSearchPublicationsArgs,
+): PaginatedReadResult;
+
+/**
+ * Search for publications based on a defined criteria
+ *
+ * This signature supports [React Suspense](https://react.dev/reference/react/Suspense).
+ *
+ * ```tsx
+ * const { data } = useSearchPublications({
+ * query: 'foo',
+ * suspense: true,
+ * });
+ *
+ * console.log(data);
+ * ```
+ *
+ * Use [startTransition](https://react.dev/reference/react/startTransition) to avoid to re-suspend the component.
+ *
+ * ```tsx
+ * const [query, setQuery] = useState('foo');
+ *
+ * const { data } = useSearchPublications({
+ * query,
+ * suspense: true,
+ * });
+ *
+ * const search = () => {
+ * startTransition(() => {
+ * setQuery('bar');
+ * });
+ * };
+ * ```
+ *
+ * @experimental This API can change without notice
+ * @category Discovery
+ * @group Hooks
+ */
+export function useSearchPublications(
+ args: UseSuspenseSearchPublicationsArgs,
+): SuspensePaginatedResult;
+
export function useSearchPublications({
- query,
limit,
+ query,
+ suspense = false,
where,
-}: UseSearchPublicationsArgs): PaginatedReadResult {
- return usePaginatedReadResult(
- useBaseSearchPublications(
- useLensApolloClient({
- variables: useFragmentVariables({
- query,
- limit,
- where,
- statsFor: where?.metadata?.publishedOn,
- }),
+}: UseSearchPublicationsArgs & { suspense?: boolean }): SuspendablePaginatedResult<
+ PrimaryPublication[]
+> {
+ return useSuspendablePaginatedQuery({
+ suspense,
+ query: SearchPublicationsDocument,
+ options: useLensApolloClient({
+ variables: useFragmentVariables({
+ query,
+ limit,
+ where,
+ statsFor: where?.metadata?.publishedOn,
}),
- ),
- );
+ }),
+ });
}