์ธํ„ฐ๋ ‰์…˜์ด ๊ฐ€๋Šฅํ•œ ํƒœ๊ทธ ์ค‘์ฒฉ ์•ˆ์‹œํ‚ค๊ธฐ

2025. 11. 5. 16:09ใ†Trouble Shooting & Issues/Linkiving

๋ฐ˜์‘ํ˜•

๊ธฐ๋ฌ˜ํ•˜๊ฐœ

๋ชฉ์ฐจ

1. ๋ฌธ์ œ

2. ํ•ด๊ฒฐ


1. ๋ฌธ์ œ

๐Ÿ”ด ์ธํ„ฐ๋ž™์…˜ ๊ฐ€๋Šฅํ•œ ํƒœ๊ทธ๋ฅผ ์ค‘์ฒฉ์‹œํ‚ด

<Link href="/items">
  <Button size="lg" onClick={() => console.log("page")}>
    ๋กœ๊ทธ์ธ
  </Button>
</Link>

๋ฌธ์ œ์˜ ์ฝ”๋“œ๋กœ, ๋ณด๋ฉด Link ํƒœ๊ทธ ๋‚ด๋ถ€์— Button ํƒœ๊ทธ๊ฐ€ ๋“ค์–ด๊ฐ€ ์ค‘์ฒฉ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ์ด๋‹ค.

ํ•˜์ง€๋งŒ ์ธํ„ฐ๋ž™์…˜์ด ๊ฐ€๋Šฅํ•œ ํƒœ๊ทธ(button, a, input ๋“ฑ)๋Š” ์ค‘์ฒฉ์‹œํ‚ค์ง€ ์•Š๋Š” ๊ฒƒ์ด ํ‘œ์ค€์ด๋‹ค.

์ด๋ฒคํŠธ ๋‚ด๋ถ€์—์„œ ๋˜๋‹ค๋ฅธ ํด๋ฆญ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋‚˜ ์Šคํฌ๋ฆฐ๋ฆฌ๋”๊ฐ€ ํ˜ผ๋ž€์„ ๊ฒช์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 


2. ํ•ด๊ฒฐ

๐ŸŸข LinkButton ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

LinkButton์€ ์“ฐ์ž„์ด ์—ฌ๊ธฐ์ €๊ธฐ ๋” ์žˆ์œผ๋ฏ€๋กœ, ๊ณต์šฉ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.

wrapper ํŒจํ„ด์„ ์ ์šฉํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ˆ˜์ •ํ•ด๋ณผ ๊ฑฐ๋‹ค.

 

Button ์ปดํฌ๋„ŒํŠธ ์ˆ˜์ •

return (
    <button
      ref={ref}
      className={clsx(classes, className)}
      disabled={disabled}
      onClick={onClick}
      {...rest}
    >
      {children}
    </button>
  );

๊ธฐ์กด ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ๋Š” <button> ํƒœ๊ทธ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๋ฐฉ์‹์ด์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด ๋ฐฉ์‹์„ ์œ ์ง€ํ•˜๋ฉด LinkButton์—์„œ Button ์ปดํฌ๋„ŒํŠธ๋ฅผ importํ•˜์—ฌ wrapper๋กœ ์‚ฌ์šฉํ•˜๋”๋ผ๊ณ  ์—ฌ์ „ํžˆ ์ค‘์ฒฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

 

์—ฌ๊ธฐ์—์„œ Slot Component๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

https://www.npmjs.com/package/@radix-ui/react-slot

 

Slot์€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ž˜ํ•‘ํ•˜์ง€ ์•Š๊ณ , ์ž์‹์˜ props์™€ ์Šคํƒ€์ผ์„ ๋ณ‘ํ•ฉ์‹œ์ผœ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

์ฆ‰, ์ž์‹์„ ์ง์ ‘ ๋ Œ๋”๋งํ•˜๋˜, ๋ถ€๋ชจ์˜ ์Šคํƒ€์ผ๊ณผ ์†์„ฑ์„ ํ•ฉ์น˜๋Š” ๋А๋‚Œ์ด๋‹ค.

// โŒ ์ผ๋ฐ˜ ์ปดํฌ๋„ŒํŠธ : button์•ˆ์— Link๊ฐ€ ์ค‘์ฒฉ๋จ ( children = <Link>๋งํฌ</Link> )
<div>
  <button>
    {children}
  </button>
</div>

// โญ• slot ์ปดํฌ๋„ŒํŠธ : button์•ˆ์— Link๊ฐ€ ์ค‘์ฒฉ๋˜์ง€ ์•Š์Œ  ( children = ๋งํฌ )
<div>
  <Link>
    {children}
  </Link>
</div>

 

Slot ์‚ฌ์šฉ์„ ์œ„ํ•ด npm์œผ๋กœ ์„ค์น˜๋ฅผ ํ•ด์คฌ๋‹ค.

 

npm install -D @radix-ui/react-slot # Slot ์„ค์น˜

 

Slot์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์›๋ž˜๋Œ€๋กœ "button"์„ ์ฃผ๊ธฐ ์œ„ํ•ด Comp๋ฅผ ์ •์˜ํ•œ ํ›„, return์—์„œ button ๋Œ€์‹  Comp๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

const Comp = asChild ? Slot : "button";	// asChild๋Š” boolean์œผ๋กœ ์„ ์–ธ
// ...

return (
    <Comp
      ref={ref}
      className={clsx(classes, className)}
      disabled={disabled}
      onClick={onClick}
      {...rest}
    >
      {children}
    </Comp>
  );

 

 

LinkButton ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑ

import Link from "next/link";
import Button, { ButtonProps } from "../base/Button";

interface LinkButtonProps extends ButtonProps {
  href: string;
}

const LinkButton = ({ href, children, ...props }: LinkButtonProps) => {
  return (
    <Button asChild {...props}>
      <Link href={href}>{children}</Link>
    </Button>
  );
};

export default LinkButton;

 

LinkButtonProps๋Š” ButtonProps๋ฅผ ์ƒ์†๋ฐ›์•„์„œ href๋งŒ ์ถ”๊ฐ€ํ•˜๋„๋ก ํ–ˆ๋‹ค.

asChild๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด ์ค‘์ฒฉ ๋ฌธ์ œ๋„ ํ•ด๊ฒฐ๋œ๋‹ค.

 

 

 

 

์ฐธ๊ณ 

๋”๋ณด๊ธฐ
๋ฐ˜์‘ํ˜•