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๋ฅผ ํ์ฑํํ๋ฉด ์ค์ฒฉ ๋ฌธ์ ๋ ํด๊ฒฐ๋๋ค.
์ฐธ๊ณ
https://www.reddit.com/r/HTML/comments/lsky98/psa_you_cannot_nest_interactive_elements/
Reddit์ HTML ์ปค๋ฎค๋ํฐ
HTML ์ปค๋ฎค๋ํฐ์์ ์ด ๊ฒ์๋ฌผ์ ๋น๋กฏํ ๋ค์ํ ์ฝํ ์ธ ๋ฅผ ์ดํด๋ณด์ธ์
www.reddit.com
https://wkl0083.tistory.com/183
๐ React์์ Slot ํจํด ๊ตฌํํด๋ณด๊ธฐ – children ์กฐํฉ์ผ๋ก ์ ์ฐํ ์ปดํฌ๋ํธ ๋ง๋ค๊ธฐ
๋ฆฌ์กํธ๋ฅผ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ์ ์ฐํ๊ณ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๋๊ฐ ๋ง์ต๋๋ค. ์ด๋ด ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ ํจํด ์ค ํ๋๊ฐ ๋ฐ๋ก Slot ํจํด์ ๋๋ค.HTML์ ์ฒ๋ผ ๋์ํ๊ฒ ๋ง๋๋ ๋ฐฉ
wkl0083.tistory.com
'Trouble Shooting & Issues > Linkiving' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Next.js app router๋ก api ํจ์ ์์ฑํ๊ธฐ (0) | 2025.11.27 |
|---|---|
| [Next.js] ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๋งํฌ์ ์ธ๋ค์ผ ๊ฐ์ ธ์ค๊ธฐ (0) | 2025.11.17 |
| [WIP] CardList Pagination ๊ตฌํํ๊ธฐ (0) | 2025.11.04 |
| ๊ธฐ๋ณธ TextArea์ ํ์ฅ์ฑ ๊ณ ๋ฏผ (์ ์ ? ๋์ ?) (0) | 2025.11.03 |
| [WIP]npm์์ pnpm์ผ๋ก ๋ฐ๊ฟจ๋๋ storybook action์ด ์๋จนํ๋ค (0) | 2025.11.03 |
GitHub