한국어로는 인터페이스 분리 원칙
이라고 부른다.
객체는 자신이 사용하지 않는 메소드에 의존하지 않아야 한다는 원칙이다.
이 원칙을 React에 대입하자면 컴포넌트가 자신이 사용하지 않는 props에 의존하지 않아야 한다고 보면 된다.
유튜브처럼 비디오를 나열해 보여주는 컴포넌트를 예시로 들겠다.
// VideoList.tsx
type Video = {
title: string
duration: number
coverUrl: string
}
type Props = {
items: Array<Video>
}
const VideoList = ({ items }) => {
return (
<ul>
{items.map(item =>
<Thumbnail
key={item.title}
video={item}
/>
)}
</ul>
)
}
// Thumbnail.tsx
type Props = {
video: Video
}
const Thumbnail = ({ video }: Props) => {
return <img src={video.coverUrl} />
}
썸네일 이미지를 보여주는 Thumbnail
컴포넌트는 Video
타입의 props를 전달받고 있지만 그 중에서 coverUrl
만 사용하고 있기 때문에 위 코드는 ISP를 위반하는 코드이다.
이 상황에서 만약 일반 동영상 타입인 Video
말고 LiveStream
이라는 실시간 스트리밍 타입을 추가하게 된다면 기존 Thumbnail
컴포넌트를 재사용할 수 없게 된다.
type Props = {
items: Array<Video | LiveStream>
}
const VideoList = ({ items }) => {
return (
<ul>
{items.map(item => {
if ('coverUrl' in item) {
return <Thumbnail video={item} />
} else {
return <LiveStreamThumbnail liveStream={item} />
}
})}
</ul>
)
}
LiveStreamThumbnail
은 결국 Thumbnail
과 같거나 비슷한 방식으로 이미지만 보여주는 역할을 할 것이라 코드에 중복이 발생할 것이고, 두 컴포넌트들을 사용하는 VideoList
컴포넌트의 코드 또한 복잡해진다.
이 문제는 결국 Thumbnail
에서 실제로 사용하는 이미지 url만 받지 않고 Video
객체를 불필요하게 통째로 받아와 사용하기 때문에 발생한다.
ISP를 준수하도록 Thumbnail
코드를 개선해 이 문제를 해결할 수 있다.
type Props = {
coverUrl: string
}
const Thumbnail = ({ coverUrl }: Props) => {
return <img src={coverUrl} />
}
이런 식으로 컴포넌트에서 실제로 사용하는 props만 받아 컴포넌트끼리의 의존성을 최소화함으로써 결합도를 낮추고 코드 재사용성을 높일 수 있다.
- ISP는 객체가 자신이 사용하지 않는 메서드에 의존하지 않아야 한다는 원칙이다.
- 실제로 컴포넌트에서 사용하는 props만 받아 ISP를 준수한다.
- ISP를 준수함으로써 컴포넌트끼리의 의존성을 낮추고 코드 재사용성을 높일 수 있다.