From 2b8a5558c6d88f37346346c5f9db2cdd0073f83f Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 31 Aug 2023 16:33:01 +0700 Subject: [PATCH] feat(Cell Suspense): Allow Cells to not Suspend (#9106) --- .../web/src/components/cell/cellTypes.tsx | 24 ++++++------ .../components/cell/createSuspendingCell.tsx | 38 ++++++++++++++----- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/web/src/components/cell/cellTypes.tsx b/packages/web/src/components/cell/cellTypes.tsx index fa352cc3805d..91ac3f19dfef 100644 --- a/packages/web/src/components/cell/cellTypes.tsx +++ b/packages/web/src/components/cell/cellTypes.tsx @@ -180,7 +180,7 @@ export interface CreateCellProps { displayName?: string } -export type SuperSuccessProps = React.PropsWithChildren< +export type SuspendingSuccessProps = React.PropsWithChildren< Record > & { queryRef: QueryReference // from useBackgroundQuery @@ -208,18 +208,20 @@ export interface SuspenseCellQueryResult< networkStatus?: NetworkStatus called: boolean // can we assume if we have a queryRef its called? - // Stuff not here: - // observable: ObservableQuery - // previousData?: TData, May not be relevant anymore. + // Stuff not here compared to useQuery: + // observable: ObservableQuery // Lenz: internal implementation detail, should not be required anymore + // previousData?: TData, // emulating suspense, not required in the new Suspense model // ObservableQueryFields 👇 - // subscribeToMore ~ returned from useSuspenseQuery. What would users use this for? - // updateQuery - // refetch - // reobserve - // variables <~ variables passed to the query. Startup club have reported using this, but why? - // fetchMore - // startPolling <~ Apollo team are not ready to expose Polling yet + // subscribeToMore ~ returned from useSuspenseQuery but not useReadQuery. Apollo team **may** expose from useReadQuery. + // updateQuery <~ May not be necessary in the Suspense model + // refetch ~ <~ refetch signature is different in useQuery vs useSuspenseQuery. Apollo team need an internal discussion. + // reobserve <~ avoid + // variables <~ variables passed to the query, useful if you updated the variables using updateQuery or refetch. Apollo team need an internal discussion. + + // Polling: Apollo team are not ready to expose Polling yet. Unlikely to be shipped in the next few months. + // But possible to re-implement this in a different way using setInternal or client.startPolling + // startPolling // stopPolling // ~~~ } diff --git a/packages/web/src/components/cell/createSuspendingCell.tsx b/packages/web/src/components/cell/createSuspendingCell.tsx index e4574ff7b435..e78d0dfd8088 100644 --- a/packages/web/src/components/cell/createSuspendingCell.tsx +++ b/packages/web/src/components/cell/createSuspendingCell.tsx @@ -11,7 +11,7 @@ import { CellErrorBoundary, FallbackProps } from './CellErrorBoundary' import { CreateCellProps, DataObject, - SuperSuccessProps, + SuspendingSuccessProps, SuspenseCellQueryResult, } from './cellTypes' import { isDataEmpty } from './isCellEmpty' @@ -44,13 +44,13 @@ export function createSuspendingCell< }), afterQuery = (data) => ({ ...data }), isEmpty = isDataEmpty, - Loading = () => <>Loading..., + Loading, Failure, Empty, Success, displayName = 'Cell', } = createCellProps - function SuperSuccess(props: SuperSuccessProps) { + function SuspendingSuccess(props: SuspendingSuccessProps) { const { queryRef, suspenseQueryResult, userProps } = props const { data, networkStatus } = useReadQuery(queryRef) const afterQueryData = afterQuery(data as DataObject) @@ -79,7 +79,7 @@ export function createSuspendingCell< ) } - SuperSuccess.displayName = displayName + SuspendingSuccess.displayName = displayName // @NOTE: Note that we are returning a HoC here! return (props: CellProps) => { @@ -125,17 +125,35 @@ export function createSuspendingCell< ) } - return ( - + const wrapInSuspenseIfLoadingPresent = ( + suspendingSuccessElement: React.ReactNode, + LoadingComponent: typeof Loading + ) => { + if (!LoadingComponent) { + return suspendingSuccessElement + } + + return ( } + fallback={ + + } > - + ) + } + + return ( + + {wrapInSuspenseIfLoadingPresent( + } suspenseQueryResult={suspenseQueryResult} - /> - + />, + Loading + )} ) }