Render props и HOC (обзор)
Обзорный урок про два «классических» паттерна переиспользования логики — render props и HOC — и про то, почему сегодня их чаще заменяют кастомные хуки.
Render prop — проп-функция, которой компонент передаёт свои данные, чтобы вызывающий сам решил, что отрисовать. HOC (higher-order component) — функция, которая принимает компонент и возвращает новый, обёрнутый.
Зачем это было нужно
До хуков (React < 16.8) не было способа переиспользовать логику с состоянием между компонентами. Render props и HOC появились именно для этого: «поделиться» подпиской, загрузкой данных, отслеживанием мыши без копипаста. Сегодня ту же задачу решают кастомные хуки — короче и без вложенности, — но эти паттерны живут в множестве библиотек, поэтому их важно узнавать.
Render props
Компонент инкапсулирует логику и вызывает функцию-проп (часто children как функцию), передавая ей результат. Что рисовать — решает потребитель.
function MouseTracker({ children }) {
const [pos, setPos] = React.useState({ x: 0, y: 0 });
return (
<div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
{children(pos)}
</div>
);
}
// потребитель сам решает, как отрисовать координаты
<MouseTracker>
{(pos) => <p>Курсор: {pos.x}, {pos.y}</p>}
</MouseTracker>
Плюс — гибкость, минус — «пирамида» вложенных функций при нескольких таких компонентах (callback hell в JSX).
HOC — компонент высшего порядка
HOC — функция withX(Component) => EnhancedComponent. Она оборачивает компонент, добавляя ему пропсы или поведение. По соглашению имя начинается с with.
function withUser(Component) {
return function Wrapped(props) {
const user = useCurrentUser(); // некий источник данных
return <Component {...props} user={user} />;
};
}
const ProfileWithUser = withUser(Profile);
Минусы HOC: «обёрточный ад» в дереве компонентов, коллизии имён пропсов, неочевидно, откуда пришёл проп. Поэтому react-redux, например, перешёл с HOC connect на хуки useSelector/useDispatch.
Сравнение подходов
| Паттерн | Как переиспользует логику | Главный минус |
| Render props | проп-функция получает данные | вложенность функций в JSX |
| HOC | обёртка добавляет пропсы | «обёрточный ад», скрытые пропсы |
| Кастомный хук | вызов функции use… в теле | почти нет — предпочтительный способ |
Что выбирать сегодня
Для новой переиспользуемой логики берите кастомный хук — он плоский и явный. Render props и HOC оставьте для случаев, где нужно управлять самой отрисовкой извне (render prop) или встроиться в API существующей библиотеки (HOC). Узнавать их в чужом коде обязательно.
Итог
- Render props и HOC — доходулевые способы делиться логикой с состоянием.
- Render prop отдаёт данные функции-пропу; HOC оборачивает компонент.
- Минусы — вложенность и «обёрточный ад»; кастомные хуки их устраняют.
- Для новой логики выбирайте хуки; паттерны нужно уметь читать в чужом коде.