Render props — это паттерн, позволяющий передавать функцию как дочерний элемент компонента, предоставляя полный контроль над тем, что будет отрендерено в зависимости от состояния маршрутизации. В контексте React Router render props традиционно использовались для условного рендеринга компонентов на основе текущего маршрута, параметров URL или состояния навигации.
Пример базового использования render props с компонентом
<Route>:
import { Route } from 'react-router-dom';
<Route path="/profile" render={({ match, location, history }) => (
<Profile match={match} location={location} history={history} />
)} />
Ключевые моменты:
match содержит информацию о совпадении маршрута,
включая параметры URL.location хранит текущий адрес, search-параметры и
hash.history позволяет программно управлять навигацией
(push, replace, goBack и т.д.).<Route> с render props.<Routes> и хук
useNavigateНачиная с React Router v6, render props устарели, а основной подход
изменился на декларативный. Вместо render и
component используется <Routes> с
вложенными <Route> и хуки для доступа к истории и
параметрам маршрута.
Пример рефакторинга старого render props кода:
Старый синтаксис:
<Route path="/profile/:id" render={({ match }) => (
<Profile id={match.params.id} />
)} />
Новый синтаксис:
import { Routes, Route, useParams } from 'react-router-dom';
function ProfileWrapper() {
const { id } = useParams();
return <Profile id={id} />;
}
<Routes>
<Route path="/profile/:id" element={<ProfileWrapper />} />
</Routes>
Преимущества нового подхода:
<Routes> и <Route> позволяют легко
читать структуру маршрутов.useParams, useLocation,
useNavigate позволяют избавиться от render props и явного
пропс-дриллинга.useParams() — получение динамических параметров
маршрута.useNavigate() — программная навигация без необходимости
обращаться к history через props.useLocation() — доступ к текущему URL,
search-параметрам и hash.useMatch(pattern) — проверка совпадения маршрута с
конкретным паттерном.Пример замены render props с несколькими условиями:
Старый вариант:
<Route path="/dashboard" render={({ history }) => (
isAuthenticated ? <Dashboard history={history} /> : <Redirect to="/login" />
)} />
Новый вариант:
import { Navigate, useNavigate } from 'react-router-dom';
function DashboardWrapper({ isAuthenticated }) {
const navigate = useNavigate();
if (!isAuthenticated) return <Navigate to="/login" />;
return <Dashboard navigate={navigate} />;
}
<Routes>
<Route path="/dashboard" element={<DashboardWrapper isAuthenticated={isAuthenticated} />} />
</Routes>
<Route> с атрибутом
render.element и
хуки: использовать <Routes> и
<Route> с новым API.<Routes> с хуками, чтобы упростить поддержку.Navigate и useNavigate для
обработки защищенных маршрутов и редиректов.Рефакторинг render props делает код более читаемым, современным и поддерживаемым, снижает вероятность ошибок при передаче параметров и повышает производительность приложения.