재사용 가능한 컴포넌트 만들기(1) - map 에 이어서 생각보다 컴포넌트 내에 자바스크립트 코드를 혼재해서 쓰는 경우가 많다는 걸 느꼈다.
전에 구현한 DynamicRender 로 수정하는 과정에서 조건문에 따른 다른 컴포넌트를 렌더링 해야 할때 삼항연산자나 && 연산자를 사용하게 되는데 이 부분도 재사용 가능한 컴포넌트로 구현할 수 있지 않을까 하는 생각이 들었다.
아래 isFolded 가 true 일때만
<ul>태그가 보여진다.
보통 이런식으로 자주 쓰이는데, 아래는 간단한 편이지만 삼항연산자를 사용하거나 로직이 조금만 길어져도 가독성이 매우 떨어진다ㅠㅠ
const DropDown = ({timeList}) => {
const [isFolded, setIsFolded] = useState(false);
const handleFolder = () => {
setIsFolded((prev) => !prev);
};
const handleTime = (time) => {
console.log(time);
};
const renderTime = (time) => (
<li key={time.label} onClick={() => handleTime(time.label)}>
{time.label}
</li>
)
return (
<>
<div onClick={handleFolder}>클릭</div>
{isFolded && (
<ul>
<DynamicRender data={timeList} renderItem={renderTime} />
</ul>
)}
</>
);
};
export default DropDown;
ConditionalDisplay 컴포넌트는 주어진 조건에 따라 특정 컴포넌트를 화면에 표시하거나 대체 컴포넌트를 표시할 수 있다.
삼항 연산자 대체: alternativeComponent를 활용하여 삼항 연산자를 대체할 수 있다.
&& 연산자 대체: alternativeComponent가 없을 때는 alternativeComponent 는 null 을 반환하므로 && 연산자처럼 사용할 수 있어서 조건이 참일 때에만 children을 표시할 수 있다.
🔸실제 코드🔸
import React from "react";
type ConditionalDisplayProps = {
condition: boolean;
children: React.ReactNode;
alternativeComponent?: React.ReactNode | null;
};
const ConditionalDisplay: React.FC<ConditionalDisplayProps> = ({
condition,
children,
alternativeComponent,
}) => {
return condition ? <>{children}</> : <>{alternativeComponent}</>;
};
export default ConditionalDisplay;
ConditionalDisplay 라는 컴포넌트를 만들어서 실제로 프로젝트에 적용해보고 느낀점을 적어보면 아래와 같다.
재사용성 증가 : 동일한 방식으로 조건문에 따라 컴포넌트를 렌더링할때 컴포넌트를 그대로 사용해 코드의 재사용성이 높아졌다.
가독성 향상 : 삼항 연산자나 && 연산자와 비교하여 가독성이 좋아졌다.
코드 추상화 : ConditionalDisplay 컴포넌트명만 봐도 조건에 따라 컴포넌트를 렌더링 한다는 것을 알 수 있어서 코드 이해가 쉬워졌다.
🔸컴포넌트 내에 자바스크립트로 작성한 코드
return (
<>
<div onClick={handleFolder}>클릭</div>
{isFolded && (
<ul>
<DynamicRender data={timeList} renderItem={renderTime} />
</ul>
)}
</>
);
};
🔸ConditionalDisplay 컴포넌트를 활용한 코드
return (
<>
<div onClick={handleFolder}>클릭</div>
<ConditionalDisplay condition={isFolded}>
<ul>
<DynamicRender data={timeList} renderItem={renderTime} />
</ul>
</ConditionalDisplay>
</>
);
};
🔹삼항 연산자를 대체하는 경우
<기존코드>
{!isLoggedIn && <Link to="/login">로그인</Link>}
{isLoggedIn && (
<LogoutBoxStyle>
<button onClick={() => navigate("/mypage/order")}>
내정보
</button>
<button onClick={logoutHandler}>로그아웃</button>
</LogoutBoxStyle>
)}
<ConditionalDisplay 사용한 코드>
<ConditionalDisplay condition={isLoggedIn} alternativeComponent={<Link to="/login">로그인</Link>}>
<LogoutBoxStyle>
<button onClick={() => navigate("/mypage/order")}>
내정보
</button>
<button onClick={logoutHandler}>로그아웃</button>
</LogoutBoxStyle>
</ConditionalDisplay>