"><SuspenseQuery/>
We provide these components to clearly express what causes suspense at the same depth.
import { SuspenseQuery } from '@suspensive/react-query'
import { Suspense, ErrorBoundary } from '@suspensive/react'
import { PostListItem, UserProfile } from '~/components'
const PostsPage = ({ userId }) => (
<ErrorBoundary fallback={({ error }) => <>{error.message}</>}>
<Suspense fallback={'loading...'}>
<SuspenseQuery {...userQueryOptions(userId)}>
{({ data: user }) => <UserProfile key={user.id} {...user} />}
</SuspenseQuery>
<SuspenseQuery
{...postsQueryOptions(userId)}
select={(posts) => posts.filter(({ isPublic }) => isPublic)}
>
{({ data: posts }) =>
posts.map((post) => <PostListItem key={post.id} {...post} />)
}
</SuspenseQuery>
</Suspense>
</ErrorBoundary>
)
Because the existing useSuspenseQuery is a hook, it creates components with names such as UserInfo and PostList to place Suspense and ErrorBoundary on the parent. This makes it difficult to predict what suspense and errors will be thrown inside UserInfo and PostList.
// posts/page.tsx
import { Suspense, ErrorBoundary } from '@suspensive/react'
import { UserInfo } from './components/UserInfo'
import { PostList } from './components/PostList'
const PostsPage = ({ userId }) => (
<ErrorBoundary fallback={({ error }) => <>{error.message}</>}>
<Suspense fallback={'loading...'}>
<UserInfo userId={userId} />{' '}
{/* It is difficult to predict whether a suspension will occur internally. */}
<PostList userId={userId} />{' '}
{/* It is difficult to predict whether a suspension will occur internally. */}
</Suspense>
</ErrorBoundary>
)
// posts/components/UserInfo.tsx
import { useSuspenseQuery } from '@suspensive/react-query'
import { UserProfile } from '~/components'
// From the perspective of using this component, it is impossible to predict whether Suspense will occur internally just by the name UserInfo.
const UserInfo = ({ userId }) => {
// We need to create this component just for data-fetching.
const { data: user } = useSuspenseQuery(userQueryOptions(userId))
return <UserProfile {...user} />
}
// posts/components/PostList.tsx
import { useSuspenseQuery } from '@suspensive/react-query'
import { PostListItem } from '~/components'
// From the perspective of using this component, it is impossible to predict whether a suspense will occur internally based on the name PostList alone.
const PostList = ({ userId }) => {
// We need to create this component just for data-fetching.
const { data: posts } = useSuspenseQuery({
...postsQueryOptions(userId);
select: (posts) => posts.filter(({ isPublic }) => isPublic),
})
return (
<>
{posts.map((post) => (
<PostListItem {...post} />
))}
</>
)
}