SuspenseQuery
๊ฐ์ depth์์ Suspense๋ฅผ ๋ฐ์์ํค๋ ๊ฒ์ด ๋ฌด์์ธ์ง ๋ช ํํ๊ฒ ํํํ๊ธฐ ์ํด ์ด ์ปดํฌ๋ํธ๋ค์ ์ ๊ณตํฉ๋๋ค.
- data-fetching๋ง์ ์ํ UserInfo, PostList์ ๊ฐ์ depth๋ฅผ ์ ๊ฑฐํ๊ธฐ ๋๋ฌธ์ prop-drilling๋ ์ ๊ฑฐ๋ฉ๋๋ค.
- Suspense, ErrorBoundary์ ๋ฒ์ ๋ณ๊ฒฝ๋ ๊ฐ๋จํด์ง๋๋ค. query์ ๋ณ๋ ฌ์ฒ๋ฆฌ๋ ๋ ์ฝ์ต๋๋ค.
- Page ์ปดํฌ๋ํธ ๋ด์์ data-fetching์ ๋ชจ๋ ๊ด์ฅํ๊ธฐ ๋๋ฌธ์ ๋ด๋ถ์ ์ปดํฌ๋ํธ๋ presentationalํ๋ฏ๋ก ์ปดํฌ๋ํธ๋ฅผ ๋ถ๋ฆฌํ๊ธฐ ์ฝ์ต๋๋ค.
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>
)
๋๊ธฐ: useSuspenseQuery๊ฐ ๋ช ํํ ๋๋ฌ๋์ง ์์
๊ธฐ์กด์ useSuspenseQuery๋ ํ ์ด๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ์ Suspense, ErrorBoundary๋ฅผ ๋ฐฐ์นํ๊ธฐ ์ํด UserInfo, PostList์ ๊ฐ์ ์ด๋ฆ์ ๊ฐ์ง ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ฒ ํฉ๋๋ค. ์ด๊ฒ์ UserInfo, PostList ๋ด๋ถ์์ ๋์ ธ์ง suspense์ error๊ฐ ์์์ง ์์ธกํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
// 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} />{' '}
{/* ๋ด๋ถ์ ์ผ๋ก Suspense๋ฅผ ๋ฐ์ํ ์ง ์์ํ๊ธฐ ์ด๋ ต์ต๋๋ค. */}
<PostList userId={userId} />{' '}
{/* ๋ด๋ถ์ ์ผ๋ก Suspense๋ฅผ ๋ฐ์ํ ์ง ์์ํ๊ธฐ ์ด๋ ต์ต๋๋ค. */}
</Suspense>
</ErrorBoundary>
)
// posts/components/UserInfo.tsx
import { useSuspenseQuery } from '@suspensive/react-query'
import { UserProfile } from '~/components'
// ์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ์
์ฅ์์๋ UserInfo๋ผ๋ ์ด๋ฆ๋ง์ผ๋ก๋ ๋ด๋ถ์ ์ผ๋ก Suspense๋ฅผ ๋ฐ์์ํค๋ ์ง ์์ธกํ ์ ์์ต๋๋ค.
const UserInfo = ({ userId }) => {
// 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'
// ์ด ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ ์
์ฅ์์๋ PostList๋ผ๋ ์ด๋ฆ๋ง์ผ๋ก๋ ๋ด๋ถ์ ์ผ๋ก Suspense๋ฅผ ๋ฐ์์ํค๋ ์ง ์์ธกํ ์ ์์ต๋๋ค.
const PostList = ({ userId }) => {
// data-fetching๋ง์ ์ํ ์ด ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
const { data: posts } = useSuspenseQuery({
...postsQueryOptions(userId),
select: (posts) => posts.filter(({ isPublic }) => isPublic),
})
return (
<>
{posts.map((post) => (
<PostListItem {...post} />
))}
</>
)
}
๋ฒ์ ๊ธฐ๋ก
Version | Changes |
---|---|
v3.0.0 | networkMode ๋ 'always' ๋ก ๊ณ ์ ๋์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ v3๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ๊ธฐ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์ธ์. |
์์ ๋ ๋ ์ง: