diff --git a/.changeset/dull-walls-smoke.md b/.changeset/dull-walls-smoke.md
new file mode 100644
index 000000000..06f2a8d08
--- /dev/null
+++ b/.changeset/dull-walls-smoke.md
@@ -0,0 +1,7 @@
+---
+"@lens-protocol/react": minor
+"@lens-protocol/react-native": minor
+"@lens-protocol/react-web": minor
+---
+
+**feat:** adds React Suspense support to `useSearchProfiles` hook
diff --git a/examples/web/src/discovery/UseSearchProfiles.tsx b/examples/web/src/discovery/UseSearchProfiles.tsx
index 758d8bdfc..3f1fc38d3 100644
--- a/examples/web/src/discovery/UseSearchProfiles.tsx
+++ b/examples/web/src/discovery/UseSearchProfiles.tsx
@@ -1,7 +1,6 @@
import { useSearchProfiles } from '@lens-protocol/react-web';
-import { ChangeEvent, useState } from 'react';
+import { ChangeEvent, Suspense, startTransition, useState } from 'react';
-import { ErrorMessage } from '../components/error/ErrorMessage';
import { Loading } from '../components/loading/Loading';
import { useInfiniteScroll } from '../hooks/useInfiniteScroll';
import { ProfileCard } from '../profiles/components/ProfileCard';
@@ -11,17 +10,14 @@ type SearchResultsProps = {
};
function SearchResults({ query }: SearchResultsProps) {
- const { data, error, loading, hasMore, observeRef } = useInfiniteScroll(
- useSearchProfiles({ query }),
+ const { data, hasMore, observeRef } = useInfiniteScroll(
+ useSearchProfiles({ query, suspense: true }),
);
- if (loading) return ;
-
- if (error) return ;
-
if (data.length === 0) {
return
No profiles found
;
}
+
return (
{data.map((profile) => (
@@ -37,7 +33,9 @@ export function UseSearchProfiles() {
const [selectedQuery, setSelectedQuery] = useState();
const handleSubmit = () => {
- setSelectedQuery(inputValue);
+ startTransition(() => {
+ setSelectedQuery(inputValue);
+ });
};
const handleChange = (e: ChangeEvent) => {
@@ -53,7 +51,10 @@ export function UseSearchProfiles() {
- {selectedQuery && }
+
+ }>
+ {selectedQuery && }
+
);
}
diff --git a/packages/react/src/discovery/useSearchProfiles.ts b/packages/react/src/discovery/useSearchProfiles.ts
index ed720bd66..580c648d4 100644
--- a/packages/react/src/discovery/useSearchProfiles.ts
+++ b/packages/react/src/discovery/useSearchProfiles.ts
@@ -1,22 +1,37 @@
import {
Profile,
ProfileSearchRequest,
- useSearchProfiles as useBaseSearchProfiles,
+ ProfileSearchWhere,
+ SearchProfilesDocument,
} 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 useSearchProfiles} hook arguments
+ */
export type UseSearchProfilesArgs = PaginatedArgs;
+export type { ProfileSearchRequest, ProfileSearchWhere };
+
/**
- * `useSearchProfiles` is a paginated hook that lets you search for profiles based on a defined criteria
+ * {@link useSearchProfiles} hook arguments with Suspense support
*
- * @category Discovery
- * @group Hooks
+ * @experimental This API can change without notice
+ */
+export type UseSuspenseSearchProfilesArgs = SuspenseEnabled;
+
+/**
+ * `useSearchProfiles` is a paginated hook that lets you search for profiles based on a defined criteria
*
- * @example
* ```tsx
* function SearchProfiles() {
* const { data, error, loading } = useSearchProfiles({ query: 'foo' });
@@ -34,13 +49,58 @@ export type UseSearchProfilesArgs = PaginatedArgs;
* );
* }
* ```
+ *
+ * @category Discovery
+ * @group Hooks
*/
-export function useSearchProfiles(args: UseSearchProfilesArgs): PaginatedReadResult {
- return usePaginatedReadResult(
- useBaseSearchProfiles(
- useLensApolloClient({
- variables: useFragmentVariables(args),
- }),
- ),
- );
+export function useSearchProfiles(args: UseSearchProfilesArgs): PaginatedReadResult;
+
+/**
+ * `useSearchProfiles` is a paginated hook that lets you search for profiles based on a defined criteria
+ *
+ * This signature supports [React Suspense](https://react.dev/reference/react/Suspense).
+ *
+ * ```tsx
+ * const { data } = useSearchProfiles({
+ * 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('bob');
+ *
+ * const { data } = useSearchProfiles({
+ * query,
+ * suspense: true,
+ * });
+ *
+ * const search = startTransition(() => {
+ * setQuery('foo');
+ * });
+ * ```
+ *
+ * @experimental This API can change without notice
+ * @category Discovery
+ * @group Hooks
+ */
+export function useSearchProfiles(
+ args: UseSuspenseSearchProfilesArgs,
+): SuspensePaginatedResult;
+
+export function useSearchProfiles({
+ suspense = false,
+ ...args
+}: UseSearchProfilesArgs & { suspense?: boolean }): SuspendablePaginatedResult {
+ return useSuspendablePaginatedQuery({
+ suspense,
+ query: SearchProfilesDocument,
+ options: useLensApolloClient({
+ variables: useFragmentVariables(args),
+ }),
+ });
}