본문으로 건너뛰기

성능 및 요청 워터폴

// Get the user
const userQuery = useQuery(() => ({
queryKey: ['user', email],
queryFn: getUserByEmail,
}))

const userId = () => userQuery.data?.id

// Then get the user's projects
const projectsQuery = useQuery(() => ({
queryKey: ['projects', userId()],
queryFn: getProjectsByUser,
// The query will not execute until the userId exists
enabled: !!userId(),
}))

중첩 컴포넌트 워터폴은 부모 컴포넌트와 자식 컴포넌트가 모두 쿼리를 포함하고, 부모가 자신의 쿼리가 완료될 때까지 자식을 렌더링하지 않는 경우입니다.

import { Switch, Match } from 'solid-js'

function Article(props) {
const articleQuery = useQuery(() => ({
queryKey: ['article', props.id],
queryFn: getArticleById,
}))

return (
<Switch>
<Match when={articleQuery.isPending}>
Loading article...
</Match>
<Match when={articleQuery.isSuccess}>
<ArticleHeader articleData={articleQuery.data} />
<ArticleBody articleData={articleQuery.data} />
<Comments id={props.id} />
</Match>
</Switch>
)
}

function Comments(props) {
const commentsQuery = useQuery(() => ({
queryKey: ['article-comments', props.id],
queryFn: getArticleCommentsById,
}))

...
}
import { Switch, Match, Show } from 'solid-js'

function Article(props) {
const articleQuery = useQuery(() => ({
queryKey: ['article', props.id],
queryFn: getArticleById,
}))

const commentsQuery = useQuery(() => ({
queryKey: ['article-comments', props.id],
queryFn: getArticleCommentsById,
}))

return (
<Switch>
<Match when={articleQuery.isPending}>Loading article...</Match>
<Match when={articleQuery.isSuccess}>
<ArticleHeader articleData={articleQuery.data} />
<ArticleBody articleData={articleQuery.data} />
<Switch>
<Match when={commentsQuery.isPending}>Loading comments...</Match>
<Match when={commentsQuery.isSuccess}>
<Comments commentsData={commentsQuery.data} />
</Match>
</Switch>
</Match>
</Switch>
)
}

이제 두 쿼리를 병렬로 가져옵니다.

import { Switch, Match, For } from 'solid-js'

function Feed() {
const feedQuery = useQuery(() => ({
queryKey: ['feed'],
queryFn: getFeed,
}))

return (
<Switch>
<Match when={feedQuery.isPending}>
Loading feed...
</Match>
<Match when={feedQuery.isSuccess}>
<For each={feedQuery.data}>
{(feedItem) => {
if (feedItem.type === 'GRAPH') {
return <GraphFeedItem feedItem={feedItem} />
}
return <StandardFeedItem feedItem={feedItem} />
}}
</For>
</Match>
</Switch>
)
}

function GraphFeedItem(props) {
const graphQuery = useQuery(() => ({
queryKey: ['graph', props.feedItem.id],
queryFn: getGraphDataById,
}))

...
}

이 예제에서는 쿼리를 부모로 끌어올리거나 프리페치를 추가하는 것만으로는 워터폴을 간단히 평탄화할 수 없습니다. 이 가이드의 시작 부분에 있는 종속 쿼리 예제와 마찬가지로, 한 가지 방법은 getFeed 쿼리에 그래프 데이터를 포함하도록 API를 리팩터링하는 것입니다.

import { lazy, Switch, Match, For } from 'solid-js'

// This lazy loads the GraphFeedItem component, meaning
// it wont start loading until something renders it
const GraphFeedItem = lazy(() => import('./GraphFeedItem'))

function Feed() {
const feedQuery = useQuery(() => ({
queryKey: ['feed'],
queryFn: getFeed,
}))

return (
<Switch>
<Match when={feedQuery.isPending}>
Loading feed...
</Match>
<Match when={feedQuery.isSuccess}>
<For each={feedQuery.data}>
{(feedItem) => {
if (feedItem.type === 'GRAPH') {
return <GraphFeedItem feedItem={feedItem} />
}
return <StandardFeedItem feedItem={feedItem} />
}}
</For>
</Match>
</Switch>
)
}

// GraphFeedItem.tsx
function GraphFeedItem(props) {
const graphQuery = useQuery(() => ({
queryKey: ['graph', props.feedItem.id],
queryFn: getGraphDataById,
}))

...
}