[Next.js + Typescript] 컴포넌트 자체를 넘겨받아 렌더링하기
2024. 12. 17. 14:01
반응형
'공유하기' 동작을 하는 버튼이 여기저기서 쓰여 공통 컴포넌트로 만들었는데,
이게 때에 따라 [버튼]이기도, [아이콘]이기도 해야했다.
아래와 같이 컴포넌트<Button>, <Icon> 자체를 넘겨받아 렌더링해줄 수 있도록 했다.
import { usePathname, useSearchParams } from 'next/navigation';
import Button, { ButtonProps } from '@/components/commons/Button';
import { toast } from 'react-toastify';
import { ComponentProps, ElementType, ReactNode } from 'react';
type Props<T extends ElementType> = {
as?: T; // 동적으로 렌더링할 컴포넌트
children?: ReactNode;
successMsg?: string;
errorMsg?: string;
} & ComponentProps<T>;
/**
*
* 현재 url을 복사하는 컴포넌트
*
* */
const CopyComponent = <T extends ElementType>({
as = Button,
children,
successMsg = 'url이 복사되었습니다.',
errorMsg = '오류가 발생했습니다.',
...props
}: Props<T>) => {
const pathname = usePathname();
const searchParams = useSearchParams();
const Component = as;
const handleCopy = async () => {
try {
const queryString = searchParams.toString();
const fullUrl = `${window.location.origin}${pathname}${
queryString ? `?${queryString}` : ''
}`;
await navigator.clipboard.writeText(fullUrl);
toast.success(successMsg);
} catch (error) {
toast.error(errorMsg);
}
};
return (
<Component {...props} onClick={handleCopy}>
{children}
</Component>
);
};
export default CopyComponent;
// 버튼형태로 가져다 사용할 때
<CopyComponent as={Button} $rightIcon="share" $variant="outlinePrimary">
공유하기
</CopyComponent>
// 아이콘형태로 가져다 사용할 때
<CopyComponent as={Icon} name="share" />
반응형
'한 걸음 > React & Next.js' 카테고리의 다른 글
[React] context API 기본구조 (0) | 2024.11.25 |
---|---|
build 결과물에서 정보를 숨기고 싶을 때 (0) | 2024.07.17 |
[npm] 라이브러리 배포 시, subpath로 깔끔하게 내보내기 (0) | 2024.06.21 |
[React] svg icon 컴포넌트화해서 사용하기 (0) | 2024.06.04 |
[styled-components + typescript] 커스텀 컴포넌트에 기본 attributes 가져오기 (0) | 2024.05.29 |