Как применять принцип единственной ответственности к React-компонентам и хукам?
SOLID во фронтенде
В React SRP означает: компонент отвечает за разметку, а загрузка данных, бизнес-правила и побочные эффекты уходят в кастомные хуки и чистые функции — у каждой части своя причина меняться.
Признаки нарушения
- Компонент на 300+ строк, где рядом
fetch, валидация формы, форматирование дат и JSX. - Пять несвязанных
useEffectи десятокuseStateв одном месте. - Чтобы поправить вёрстку, приходится разбираться в логике ретраев.
Как резать
- Данные и их жизненный цикл — кастомный хук (
useUser) или React Query. - Преобразования — чистые функции вне компонента: тестируются без рендера.
- Разметка — презентационный компонент, получающий готовые пропсы.
function useUser(id) {
const [user, setUser] = useState(null);
useEffect(() => {
let alive = true;
fetchUser(id).then(u => alive && setUser(u));
return () => { alive = false; };
}, [id]);
return user;
}
function UserCard({ id }) {
const user = useUser(id);
return user ? <h2>{formatName(user)}</h2> : <Spinner />;
}Граница
Хук, возвращающий 15 значений, — тот же «божественный объект», просто перенесённый. Кнопку на 10 строк дробить незачем.
Коротко для собеседования
Компонент рисует, а данные, эффекты и расчёты живут в кастомных хуках и чистых функциях — у каждой части своя причина меняться. Роль контейнера из Container/Presentational сейчас обычно играет хук; не стоит плодить хуки-монстры и дробить тривиальные компоненты.