📄 참고자료
Effective Component 지속 가능한 성장과 컴포넌트
🎇 변화
우리는 제품을 개발하면서 수많은 변경을 마주한다.
사용자는 우리가 만든 제품을 어려움 없이 잘 사용해야 한다.
디자인, API, 제품의 방향 언제든 바뀔 수 있다.
좋은 제품을 만들기 위해서는 변화는 필수다.
우리가 만드는 제품은 변화를 겪으면서 올바른 방향으로 성장한다.
우리는 따지고보면, 제품을 성장시키고 있는 것이다.
제품의 변화란, 놓치고 있었던 고객의 니즈를 발견하는 것과 같다.
무엇이 변경될지 알았으면 정말 좋았을 것이다. 변경은 예측하지 못한다.
우리는 예측하려 하지 말고, 대응하자.
변경에 유연한 컴포넌트 만들기
우리는 컴포넌트를 잘 만들어서 변경에 유연하게 대응할 수 있도록 해야 한다.
변경에 유연한 컴포넌트는 아래와 같다.
1. Headless 기반 추상화
2. 컴포넌트는 한가지 역할만, 혹은 컴포넌트들의 조합으로 만들자.
3. 도메인을 포함한 컴포넌트와 그렇지 않은 컴포넌트
🥇 Headless UI 기반 추상화
컴포넌트는 크게 세가지 역할을 한다.
1. 데이터관리
- 외부에서 주입받은 데이터나 상태와 같은 내부 데이터를 관리
2. UI 그리기
- 데이터가 사용자에게 어떻게 보여질지 정의
3. 사용자와 상호작용
- 클릭과 같이 사용자와 어떻게 상호작용 할 지
Headless UI란,
UI(스타일링)을 제외하고, 상태나 데이터와 관련된 부분은 따로 다루는 패턴
`캘린더 컴포넌트` 를 예시로 들어보자.
- 캘린더에 보여줄 데이터는 `useCalaner hook` 으로 분리한다.
- 그리고, 캘린더 UI에 넣어주는 것이다.
나중에 캘린더 UI가 변경되었을 때, 데이터를 건들일 필요가 없으므로 UI변경에만 집중할 수 있다.
즉 이처럼, UI를 관심사에서 제외할 수 있다. 오로지 데이터에만 집중해서 모듈화 할 수 있다.
🥈 컴포넌트를 한가지 역할만 하는 컴포넌트 조합으로 만들자
function ReactFramerworkSelector({ defaultValue }) {
const [isOpen, openk, close] = useBoolean();
const [selected, change] = useState(defaultValue);
return (
<>
<InputButton label="React Framework" value={selected} onClick={open} />
{isOpen ? (
<Options onClose={close}>
{options.map((value) => {
return (
<Button
selected={selected === value}
onClick={() => change(value)}
>
{value}
</Button>
);
})}
</Options>
) : null}
</>
);
[문제점]
- `label` 값이 달라진다면?
- `InputButton` 이 아닌 다른 버튼을 사용하고 싶다면?
- Select 하는 부분을 다른 컴포넌트에서 사용하고 싶다면?
변경에 유연하지 못하다.
개선해보자!
- 내부 상태 `isOpen` => `Dropdown`
- 상태를 바꾸기위한 상호작용 Trigger => `Dropdown.Trigger`
- 옵션영역 열고닫힘상태 `Menu` => `Dropdown.Menu`
- 메뉴를 구성하는 각각의 Item => `Dropdown.Item`
각각의 역할을 하는 것들을 하나의 컴포넌트를 구현하고 조합한다.
[실제구현코드]
이처럼, 합성가능하도록 컴포넌트를 설계한다면,재사용, 확장이 용이하다.
- 공통적인 부분(isOpen, trigger, menu) 뽑아내 Select 라는 함수를 만든다.
- Select 함수를 FrameworkSelect 라는 컴포넌트에 활용할 수 있다.
🥉 도메인 분리하기
- 위에서 구현한 컴포넌트는 Framework 라는 특정 도메인이 있기 때문에 재사용하는데 한계가 있다.
- 컴포넌트 인터페이스는 일반적일 수록 이해하기 쉽다.
- 사람은 무언가를 파악할때 기존에 알고있던 내용으로 파악한다.
📌Action Item
1. 인터페이스를 먼저 고려하자
- 구현해야 하는 기능이 먼저 만들어져 있다 가정하고 그것을 사용하듯이 작성해보자!
- 의도가 무엇인지
- 이 컴포넌트의 기능은 무엇인지
- 어떻게 표현되어야 하는지
2. 컴포넌트를 분리하는 이유에 대해 고민하자
- 분리하면 실제로 복잡도를 낮추는가
- 분리하면 재사용 가능한 컴포넌트인가
3. 데이터 흐름을 파악해서 쉽게 구조 잡기
'🌳Frontend > etc' 카테고리의 다른 글
[FE] Next.js Unhandled Runtime Error Text content does not match server-rendered HTML (0) | 2023.09.04 |
---|---|
[FE] Next.js SSR 환경에서 흔히 겪는 에러 Server Error XXX is not defined. This error happened while generating the page. (0) | 2023.09.04 |
[FE] 실무에서 바로 쓰는 Frontend Clean Code (0) | 2023.09.03 |
프론트엔드 성능 최적화 (0) | 2023.07.05 |
package.json 의 version 과 틸드 tilde(~) 그리고 캐럿 caret(^) (0) | 2023.06.15 |