Container
) 과 표현 중심(Presentational
) 으로 분리하는 구조적 패턴이다.구성 요소
동작 흐름
Container/Presentational 패턴은 다음과 같이 역할을 분리하여 구성한다:
props
로 받으며 내부 상태를 가지지 않음.// UserList.tsx - Presentational Component
const UserList = ({ users, onSelectUser }) => (
<ul>
{users.map((user) => (
<li key={user.id} onClick={() => onSelectUser(user)}>
{user.name}
</li>
))}
</ul>
);
// UserListContainer.tsx - Container Component
class UserListContainer extends React.Component {
state = {
users: [],
};
componentDidMount() {
fetch("/api/users")
.then((res) => res.json())
.then((data) => this.setState({ users: data }));
}
handleSelectUser = (user) => {
console.log("User selected:", user);
};
render() {
return (
<UserList users={this.state.users} onSelectUser={this.handleSelectUser} />
);
}
}
props
전달이 복잡해지면 Props drilling
이 발생할 수 있다.Custom Hook
기반의 분리 방식이다.useSomething()
형태의 훅으로 상태와 이벤트 핸들러를 관리하며, UI 컴포넌트는 그대로 Presentational 역할을 유지한다.// Custom Hook 예시
function useUsers() {
const [users, setUsers] = useState([]);
useEffect(() => {
fetch("/api/users")
.then((res) => res.json())
.then(setUsers);
}, []);
return { users };
}
// UI 컴포넌트에서 사용
const UserList = () => {
const { users } = useUsers();
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};