← Назад к вопросам
Как определить что является контейнером?
1.0 Junior🔥 131 комментариев
#Soft Skills и рабочие процессы
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение контейнеров в React архитектуре
В React и современной архитектуре компонентов существует четкое разделение между контейнерами (Container Components, Smart Components) и представлениями (Presentational Components, Dumb Components). Понимание этого различия критично для масштабируемого приложения.
Основные признаки контейнера
Контейнер - это компонент, который:
- Содержит бизнес-логику - управляет состоянием, эффекты, API запросы
- Работает с данными - получает, трансформирует, передает данные
- Оборачивает другие компоненты - комбинирует несколько компонентов представления
- Редко отвечает за UI - минимальная разметка, основной фокус на логике
// КОНТЕЙНЕР - управляет логикой и состоянием
import { useEffect, useState } from react;
import UserProfile from ./UserProfile; // Presentational component
function UserProfileContainer({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUser() {
try {
const response = await fetch(`/api/users/${userId}`);
const data = await response.json();
setUser(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}
fetchUser();
}, [userId]);
// Передает только необходимые props в presentational компонент
return <UserProfile user={user} loading={loading} error={error} />;
}
export default UserProfileContainer;
Признаки Presentational компонента
// PRESENTATIONAL - только UI, получает данные через props
function UserProfile({ user, loading, error }) {
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!user) return null;
return (
<div className="bg-surface-primary p-6 rounded-lg">
<img src={user.avatar} alt={user.name} className="w-20 h-20 rounded-full" />
<h1 className="text-2xl font-bold mt-4">{user.name}</h1>
<p className="text-text-secondary">{user.email}</p>
</div>
);
}
export default UserProfile;
Паттерны контейнеров
1. Container Component (старый подход)
function CommentsContainer({ postId }) {
const [comments, setComments] = useState([]);
const [filter, setFilter] = useState(all);
const filteredComments = comments.filter(c =>
filter === all || c.status === filter
);
return (
<CommentsPresentation
comments={filteredComments}
filter={filter}
onFilterChange={setFilter}
/>
);
}
2. Custom Hook (современный подход)
Вместо оборачивания в компонент-контейнер, используй кастомный хук:
// Логика в хуке
function useComments(postId) {
const [comments, setComments] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetch() {
try {
const data = await api.getComments(postId);
setComments(data);
} finally {
setLoading(false);
}
}
fetch();
}, [postId]);
return { comments, loading };
}
// Компонент использует хук
function Comments({ postId }) {
const { comments, loading } = useComments(postId);
if (loading) return <LoadingSpinner />;
return <CommentsList comments={comments} />;
}
Как определить тип компонента на практике
// Контейнер: использует useState, useEffect, useContext, useReducer
function OrdersContainer() {
const [orders, setOrders] = useState([]);
const { userId } = useContext(AuthContext);
useEffect(() => {
// логика загрузки
}, [userId]);
return <OrdersList orders={orders} />;
}
// Presentational: чистые функции, только props
function OrdersList({ orders }) {
return (
<div className="space-y-4">
{orders.map(order => (
<OrderCard key={order.id} order={order} />
))}
</div>
);
}
Преимущества разделения
- Переиспользование логики - один контейнер может использовать разные presentational компоненты
- Простое тестирование - presentational компоненты тестируются как чистые функции
- Отделение логики от UI - изменение дизайна не требует изменения логики
- Масштабируемость - четкая структура упрощает работу в большой команде
- Понятность кода - явно видно, где логика, где UI
Modern React подход
В современном React с хуками граница между контейнером и presentational стирается. Однако принцип остается:
- Выноси логику в кастомные хуки
- Компоненты остаются максимально простыми
- Передавай только необходимые данные через props
Это делает код более модульным, тестируемым и поддерживаемым.