Skip to content

Commit

Permalink
Allow to disable React Suspense per useQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
steida committed Oct 28, 2023
1 parent c03382c commit e392fe8
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .changeset/afraid-bees-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@evolu/common-react": minor
---

Allow to disable React Suspense per useQuery

React Suspense is enabled by default but can be optionally disabled
per useQuery hook. When disabled, useQuery will not stop rendering
and will return empty rows instead.

That can be helpful to avoid waterfall when using more than one
useQuery within one React Component. In such a situation, disable
Suspense for all useQuery hooks except the last one.

Because Evolu queues queries within a microtask sequentially, all
queries will be batched within one roundtrip.

Another use case is to optimistically prefetch data that might be
needed in a future render without blocking the current render.
22 changes: 22 additions & 0 deletions packages/evolu-common-react/src/React.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,29 @@ type UseQuery<S extends Schema> = {
<QueryRow extends Row, FilterMapRow extends Row>(
queryCallback: QueryCallback<S, QueryRow>,
filterMap: FilterMap<QueryRow, FilterMapRow>,
options?: UseQueryOptions,
): QueryResult<FilterMapRow>;
};

interface UseQueryOptions {
/**
* React Suspense is enabled by default but can be optionally disabled
* per useQuery hook. When disabled, useQuery will not stop rendering
* and will return empty rows instead.
*
* That can be helpful to avoid waterfall when using more than one
* useQuery within one React Component. In such a situation, disable
* Suspense for all useQuery hooks except the last one.
*
* Because Evolu queues queries within a microtask sequentially, all
* queries will be batched within one roundtrip.
*
* Another use case is to optimistically prefetch data that might be
* needed in a future render without blocking the current render.
*/
readonly suspense?: boolean;
}

type UseMutation<S extends Schema> = () => {
/**
* Creates a new row with the given values.
Expand Down Expand Up @@ -234,6 +254,7 @@ export const ReactHooksLive = <S extends Schema>(): Layer.Layer<
>(
queryCallback: QueryCallback<S, QueryRow>,
initialFilterMap?: FilterMap<QueryRow, FilterMapRow>,
options: UseQueryOptions = {},
) => {
const query = useMemo(
() => evolu.createQuery(queryCallback),
Expand All @@ -243,6 +264,7 @@ export const ReactHooksLive = <S extends Schema>(): Layer.Layer<
const promise = useMemo(() => evolu.loadQuery(query), [query]);

if (
options.suspense !== false &&
platform.name !== "server" &&
!(loadingPromisesPromiseProp in promise)
)
Expand Down

1 comment on commit e392fe8

@vercel
Copy link

@vercel vercel bot commented on e392fe8 Oct 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

evolu – ./

evolu.vercel.app
www.evolu.dev
evolu-evolu.vercel.app
evolu-git-main-evolu.vercel.app
evolu.dev

Please sign in to comment.