В своем блоге Доминик Дорфмайстер поделился, почему стоит предпочитать композицию компонентов и ранний возврат, а не условный рендеринг нескольких состояний. Рассмотрим пример «плохого» компонента:
function Layout(props: { children: ReactNode }) {
return (
<Card>
<CardHeading>Welcome 👋</CardHeading>
<CardContent>{props.children}</CardContent>
</Card>
)
}
export function ShoppingList() {
const { data, isPending } = useQuery(/* ... */)
return (
<Layout>
{data?.assignee ? <UserInfo {...data.assignee} /> : null}
{isPending ? <Skeleton /> : null}
{!data && !isPending ? <EmptyScreen /> : null}
{data
? data.content.map((item) => (
<ShoppingItem key={item.id} {...item} />
))
: null}
</Layout>
)
}
Этот компонент плох тем, что в нем много внутренних условных рендеров, что усложняет чтение и понимание работы компонента. Если разобраться во внутренних условиях, то компонент выше можно разделить на три соответствующих состоянию запроса: во время загрузки, нет данных и есть данные. Чтобы отображать каждое состояние запроса по отдельности, используйте ранний возврат и композицию. Такой код будет проще и легче читать. Пример:
export function ShoppingList() {
const { data, isPending } = useQuery(/* ... */)
if (isPending) {
return (
<Layout>
<Skeleton />
</Layout>
)
}
if (!data) {
return (
<Layout>
<EmptyScreen />
</Layout>
)
}
return (
<Layout>
{data.assignee ? <UserInfo {...data.assignee} /> : null}
{data.content.map((item) => (
<ShoppingItem key={item.id} {...item} />
))}
</Layout>
)
}
https://tkdodo.eu/blog/component-composition-is-great-btw