Я все еще иногда использую renderProps!
Когда это позволяет избегать избыточной вложенности.
Для примера возьму такой кейс - у нас есть форма и для ее отображения нам надо получить некие значения.
Это могут быть значение редактируемой сущности, или просто дефолты, не важно.
Как это обычно пишут (упрощенно):
// Page.tsx
function Page() {
return (
<Layout>
<Header />
<Form />
<Footer />
</Layout>
)
}
// Form.tsx
function Form() {
const { pending, error, initialData } = useInitialDataRequest();
if (error) return <ErrorSplashScreen error={error} />;
if (pending) return <Spinner />;
return <FormFields initialData={initialData} />
}
// FormFields.tsx
function FormFields({ initialData }) {
return <form>
{/* ... */}
</form>
}
Теперь если мы будем навигироваться по коду мы будем проходить вот такой вот длинный путь.
A
└─► фетчинг данных для B
└──► B
└──► фетчинг данных для C
└──► C
(Этот эффект я называю - матрешкой)
Рендер пропы позволяют "вынести за скобки" подготовку данных минуя "технические" прокладки (по сути существующие просто потому, что хуки нельзя вложить в условия), что делает навигацию по коду удобнее*:
// Page.tsx
function Page() {
return (
<Layout>
<Header />
<InitialDataLoader>
{initialData => <FormFields initialData={initialData} />}
<InitialDataLoader/>
<Form />
<Footer />
</Layout>
)
}
// InitialDataLoader.tsx
function InitialDataLoader({ children }) {
const { pending, error, initialData } = useInitialDataRequest();
if (error) return <ErrorSplashScreen error={error} />;
if (pending) return <Spinner />;
return children(initialData);
}
// FormFields.tsx (ничего не изменилось)
function FormFields({ initialData }) {
return <form>
{/* ... */}
</form>
}
Теперь мы можем переходить в сразу интересующую нас часть и видеть более цельную струкру
A
└─► фетчинг данных для B
└──► B
└──► фетчинг данных для C
└──► C
Вроде мелочь, а приятно.
Только не забывайте что render пропы в таком виде будут создавать лишний рендер (children функция новая на каждый рендер), поэтому Page здесь лучше сразу обернуть в React.memo
* да, того же самого можно добиться используя контекст, и если результат вам нужен в нескольких местах, а не сразу же следующем компоненте лучше именно так и делать