2020/10/09 - [Web프론트엔드/리액트] - [React] 하이오더(HoC) 기능으로 컴포넌트 확장하기 ①
바로 지난 시간에 하이오더 컴포넌트(HoC)의 개념과 그것을 이용해 컴포넌트를 확장할 수 있다고 배웠습니다. 그래서 오늘은 실습으로 컴포넌트에 툴팁 기능을 붙여서 확장해보겠습니다. 스타일이 적용되어 있지 않은 Input 컴포넌트와 이미 withStyles()로 확장되어 있는 Button 컴포넌트 두 가지 예시로 진행하겠습니다. 먼저 HoC 작성 ㄱㄱ!
// ..\test_project\src\components\withTooltip.jsx
import React from "react";
import withStyles, { css } from "../styles/withStyles";
export default function (tooltip) {
// 확장 시킬 기본 컴포넌트 (첫글짜는 대문자 필수)
return (BaseComponent) => {
// 새로운 컴포넌트 이름 만들기
const { displayName, name: componentName } = BaseComponent;
const baseComponentName = displayName || componentName;
// 확장 컴포넌트 만들기
function ComponentWithTooltip({
isError, // 툴팁에 에러메시지를 출력
styles, // 컴포넌트에 스타일 적용
...props // 기본 컴포넌트의 프러퍼티 (전개연산자는 마지막에)
}) {
// 에러일 경우 스타일 변경
let tooltipColor = styles.default;
if (isError) {
tooltipColor = styles.error;
}
return (
<React.Fragment>
<BaseComponent {...props} />
{<div {...css(tooltipColor)}>{tooltip}</div>}
</React.Fragment>
);
}
// DOM에 보여질 확장 컴포넌트 이름
ComponentWithTooltip.displayName = `withTooltip(${baseComponentName})`;
// 기본 프로퍼티 값
ComponentWithTooltip.defaultProps = {
isError: false,
};
// 확장 컴포넌트에 또 스타일 컴포넌트 확장하기
return withStyles(({ color }) => ({
default: {
color: color.default,
},
error: {
color: color.error,
},
}))(ComponentWithTooltip);
};
}
내용은 간단합니다. 확장시킬 컴포넌트 밑에 툴팁 텍스트를 붙여주고, isError 프로퍼티로 문자 색깔을 변경하는 정도의 기능입니다. ComponentWithTooltip() 함수의 return() 부분이 핵심입니다. withStyles도 하이오더 컴포넌트라는 것을 꼭 인지하시고, 마지막 부분에 withStyles(...)(ComponentWithTooltip) 사용법 또한 중요합니다.
// ..\test_project\src\stories\Story_withTooltip.jsx
import React from "react";
import { storiesOf } from "@storybook/react";
import withTooltip from "../components/withTooltip";
import Input from "../components/Input";
import Button from "../components/Button";
const InputwithTooltip = withTooltip("아이디를 입력하세요")(Input);
const ButtonwithTooltip = withTooltip("확인 버튼을 누르세요")(Button);
storiesOf("Tooltip", module)
.addWithJSX("Inputwith", () => (
<InputwithTooltip name="id" label="아이디" isError={true} />
))
.addWithJSX("Buttonwith", () => (
<ButtonwithTooltip name="confirm" xlarge primary>
확인
</ButtonwithTooltip>
));
스토리북에 추가해봤습니다. withTooltip(...)(컴포넌트) 형태로 새로운 확장 컴포넌트가 됐습니다. 이런 식으로 툴팁 기능을 각 컴포넌트 소스에 코딩하는 것이 아닌, 하이오더 기능으로 확장을 하면 코드의 재활용이 용이합니다.
이것을 커링 함수를 이용한 데코레이터 디자인 패턴이라고도 하는데 더 공부하고 싶은 분은 검색을 추천드립니다.
JSX탭을 보시면 Input -> withTooltip -> withStyles 순으로 확장되어 있습니다. Input은 스타일이 없기 때문입니다.
이번에 JSX탭을 보시면 Button-> withStyles -> withTooltip -> withStyles 순입니다. 왜냐면 Button은 지난 시간에 이미 withStyles()을 적용한 컴포넌트이기 때문입니다. 이런 식으로 계속 붙여서 사용하면 무한 확장이 가능하지만 Button의 예시처럼 너무 많은 계층이 생기면 관리하기가 어렵기 때문에 핵심 기능만 잘 조합하는 것이 중요합니다.
그럼 오늘은 여기까지 하겠습니다.
생각보다 참 간단하죠?
2020/10/14 - [Web프론트엔드/리액트] - [React] 컨텍스트(context) 기능으로 데이터 관리하기
'웹 프론트엔드 > React 리액트 (기초)' 카테고리의 다른 글
[React] 리덕스(redux) 기능으로 데이터 관리하기 ① 기초 (0) | 2020.10.16 |
---|---|
[React] 컨텍스트(context) 기능으로 데이터 관리하기 (0) | 2020.10.14 |
[React] 하이오더(HoC) 기능으로 컴포넌트 확장하기 ① (0) | 2020.10.09 |
[React] 컴포넌트에 스타일을 적용해보자 ④ media 속성 (0) | 2020.10.08 |
[React] 컴포넌트에 스타일을 적용해보자 ③ Checkbox (0) | 2020.10.08 |
댓글