📌 headless component (헤드리스 컴포넌트)

헤드리스 컴포넌트를 설명하기 전에, `useToggle` hook을 추출하여 코드 중복을 줄이는 방법을 알아보자.
✨ 토글 컴포넌트 (Toggle Component)

토글은 단순히 특정 상태를 on/off 시키는 역할을 가진다.
아래처럼 간단히 구현할 수 있다.
const ToggleButton = () => {
const [isToggled, setIsToggled] = useState(false);
const toggle = useCallback(() => {
setIsToggled((prevState) => !prevState);
}, []);
return (
<div className="toggleContainer">
<p>Do not disturb</p>
<button onClick={toggle} className={isToggled ? "on" : "off"}>
{isToggled ? "ON" : "OFF"}
</button>
</div>
);
위의 코드를 설명하면 아래와 같다.
- `useState` hook은 초기값이 false인 상태변수 `isToggled` 를 설정한다.
const [isToggled, setIsToggled] = useState(false);
- toggle 함수는 버튼이 클릭될 때 마다 호출되고, `isToggled` 값을 false 와 true사이에서 전환한다.
const toggle = useCallback(() => {
setIsToggled((prevState) => !prevState);
}, []);
- 버튼의 모양과 텍스트는 `isToggled` 상태를 동적으로 반영한다.
<button onClick={toggle} className={isToggled ? "on" : "off"}>
{isToggled ? "ON" : "OFF"}
</button>
이제 완전히 다른 `ExpandableSection` 을 만들어본다고 가정해보자.
이컴포넌트는 섹션의 세부정보를 표시하거나 숨긴다.
제목 옆에 버튼이 있으며, 클릭하여 세부 정보를 펼치거나 접을 수 있다.

이 컴포넌트도 그다지 어렵지 않게 구현해낼 수 있다.
const ExpandableSection = ({ title, children }: ExpandableSectionType) => {
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = useCallback(() => {
setIsOpen((prevState) => !prevState);
}, []);
return (
<div>
<h2 onClick={toggleOpen}>{title}</h2>
{isOpen && <div>{children}</div>}
</div>
);
};
위의 코드를 설명하자면 아래와 같다.
- 섹션의 열고 닫힘 상태를 `useState` 인 `isOpen`에 저장한다.
const [isOpen, setIsOpen] = useState(false);
- 토글함수를 통해 `isOpen`을 true와 false로 전환할 수 있다.
const toggleOpen = useCallback(() => {
setIsOpen((prevState) => !prevState);
}, []);
- `isOpen` 상태값을 통해 섹션의 컨텐츠가 보여진다.
{isOpen && <div>{children}</div>}
💬 추상화하기
처음에 만든 `ToggleButton` 과 `ExpandableSection` 은 밀접한 유사성을 가지고 있다.
`ToggleButton` 의 on / off 상태와 `ExpandableSection` 의 펼치기 / 접기 작업이 유사하다.
이러한 공통점을 인식하면, 이 공통 기능을 별도의 기능으로 추상화 할 수 있다.
React에선 `사용자정의 hook` 을 생성해 이를 수행한다.
const useToggle = (init = false) => {
const [state, setState] = useState(init);
const toggle = useCallback(() => {
setState((prevState) => !prevState);
}, []);
return [state, toggle];
};
간단한 리팩터링이지만, UI에서 동작을 분리한다는 중요한 개념이 있다.
이 시나리오에서 사용자정의 hook은 JSX로부터 독립된 함수역할을 한다.
이처럼 UI와 데이터 동작(혹은 상태관리)을 분리하는 패턴을 이용해 만든 컴포넌트를 headless component 라 한다.
이 패턴을 따르고 있는 헤드리스 컴포넌트 라이브러리는 여러가지가 있다.
- Reakit: 접근 가능한 고급 UI 라이브러리, 툴킷, 디자인 시스템 등을 구축하기 위한 헤드리스 컴포넌트 세트를 제공합니다.
- React Table: 조립하기 위한 헤드리스 유틸리티입니다. 훅 기반이며 모든 종류의 테이블을 만들 수 있습니다.
- react-use: 여러 헤드리스 컴포넌트가 포함된 훅의 모음입니다.
📄 참고링크
'🌳Frontend > react' 카테고리의 다른 글
가장 좋은 React Custom hook 구상하기 (0) | 2023.09.17 |
---|---|
나같은 초짜 Typescript React 개발자들 용어 정리글 (0) | 2023.09.17 |
[React] useRef 알아보기 - useRef 와 ref 의 개념 및 사용 (0) | 2023.09.07 |
[Next.js] useRouter 의 Shallow Routing (0) | 2023.09.06 |
[React] 리액트 렌더링 원리 (0) | 2023.08.22 |
📌 headless component (헤드리스 컴포넌트)

헤드리스 컴포넌트를 설명하기 전에, useToggle
hook을 추출하여 코드 중복을 줄이는 방법을 알아보자.
✨ 토글 컴포넌트 (Toggle Component)

토글은 단순히 특정 상태를 on/off 시키는 역할을 가진다.
아래처럼 간단히 구현할 수 있다.
const ToggleButton = () => {
const [isToggled, setIsToggled] = useState(false);
const toggle = useCallback(() => {
setIsToggled((prevState) => !prevState);
}, []);
return (
<div className="toggleContainer">
<p>Do not disturb</p>
<button onClick={toggle} className={isToggled ? "on" : "off"}>
{isToggled ? "ON" : "OFF"}
</button>
</div>
);
위의 코드를 설명하면 아래와 같다.
useState
hook은 초기값이 false인 상태변수isToggled
를 설정한다.
const [isToggled, setIsToggled] = useState(false);
- toggle 함수는 버튼이 클릭될 때 마다 호출되고,
isToggled
값을 false 와 true사이에서 전환한다.
const toggle = useCallback(() => {
setIsToggled((prevState) => !prevState);
}, []);
- 버튼의 모양과 텍스트는
isToggled
상태를 동적으로 반영한다.
<button onClick={toggle} className={isToggled ? "on" : "off"}>
{isToggled ? "ON" : "OFF"}
</button>
이제 완전히 다른 ExpandableSection
을 만들어본다고 가정해보자.
이컴포넌트는 섹션의 세부정보를 표시하거나 숨긴다.
제목 옆에 버튼이 있으며, 클릭하여 세부 정보를 펼치거나 접을 수 있다.

이 컴포넌트도 그다지 어렵지 않게 구현해낼 수 있다.
const ExpandableSection = ({ title, children }: ExpandableSectionType) => {
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = useCallback(() => {
setIsOpen((prevState) => !prevState);
}, []);
return (
<div>
<h2 onClick={toggleOpen}>{title}</h2>
{isOpen && <div>{children}</div>}
</div>
);
};
위의 코드를 설명하자면 아래와 같다.
- 섹션의 열고 닫힘 상태를
useState
인isOpen
에 저장한다.
const [isOpen, setIsOpen] = useState(false);
- 토글함수를 통해
isOpen
을 true와 false로 전환할 수 있다.
const toggleOpen = useCallback(() => {
setIsOpen((prevState) => !prevState);
}, []);
isOpen
상태값을 통해 섹션의 컨텐츠가 보여진다.
{isOpen && <div>{children}</div>}
💬 추상화하기
처음에 만든 ToggleButton
과 ExpandableSection
은 밀접한 유사성을 가지고 있다.
ToggleButton
의 on / off 상태와 ExpandableSection
의 펼치기 / 접기 작업이 유사하다.
이러한 공통점을 인식하면, 이 공통 기능을 별도의 기능으로 추상화 할 수 있다.
React에선 사용자정의 hook
을 생성해 이를 수행한다.
const useToggle = (init = false) => {
const [state, setState] = useState(init);
const toggle = useCallback(() => {
setState((prevState) => !prevState);
}, []);
return [state, toggle];
};
간단한 리팩터링이지만, UI에서 동작을 분리한다는 중요한 개념이 있다.
이 시나리오에서 사용자정의 hook은 JSX로부터 독립된 함수역할을 한다.
이처럼 UI와 데이터 동작(혹은 상태관리)을 분리하는 패턴을 이용해 만든 컴포넌트를 headless component 라 한다.
이 패턴을 따르고 있는 헤드리스 컴포넌트 라이브러리는 여러가지가 있다.
- Reakit: 접근 가능한 고급 UI 라이브러리, 툴킷, 디자인 시스템 등을 구축하기 위한 헤드리스 컴포넌트 세트를 제공합니다.
- React Table: 조립하기 위한 헤드리스 유틸리티입니다. 훅 기반이며 모든 종류의 테이블을 만들 수 있습니다.
- react-use: 여러 헤드리스 컴포넌트가 포함된 훅의 모음입니다.
📄 참고링크
'🌳Frontend > react' 카테고리의 다른 글
가장 좋은 React Custom hook 구상하기 (0) | 2023.09.17 |
---|---|
나같은 초짜 Typescript React 개발자들 용어 정리글 (0) | 2023.09.17 |
[React] useRef 알아보기 - useRef 와 ref 의 개념 및 사용 (0) | 2023.09.07 |
[Next.js] useRouter 의 Shallow Routing (0) | 2023.09.06 |
[React] 리액트 렌더링 원리 (0) | 2023.08.22 |