Library/React

[ React ] ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ ๊ธฐ์ค€์„ ์•Œ์•„๋ณด์ž.

ma.caron_g 2025. 4. 4. 17:50

 

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ฐœํ•˜๋‹ค๋ณด๋ฉด, ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฆฌํ•ด์•ผํ•  ๊ฒƒ์ธ๊ฐ€๋ฅผ ๋งŽ์ด ๊ณ ๋ฏผํ•œ๋‹ค.

๋˜, ๋ถ„๋ฆฌํ•˜์—ฌ ์–ด๋– ํ•œ ํŒจํ„ด์„ ์ด์šฉํ•˜์—ฌ ์ž‘์„ฑํ• ์ง€๋„ ๊ณ ๋ฏผํ•œ๋‹ค.

 

์šฐ์„  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ธฐ์ค€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

 

๐Ÿฆด ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ

1. โ™ป๏ธ ์žฌ์‚ฌ์šฉ์„ฑ (Resualbility)

๐Ÿ‘‰๐Ÿป ๋™์ผํ•œ UI๋‚˜ ๊ธฐ๋Šฅ์„ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ex. Button, Modal, Card, Input

 

์ฝ”๋“œ ์ข€ ๋” ์ดํ•ดํ•˜๊ธฐ >> ์œ ํ‹ธํ•จ์ˆ˜ cn(tailwind-merge)

 

tailwind-merge

Merge Tailwind CSS classes without style conflicts. Latest version: 3.1.0, last published: 3 days ago. Start using tailwind-merge in your project by running `npm i tailwind-merge`. There are 6014 other projects in the npm registry using tailwind-merge.

www.npmjs.com

๋”๋ณด๊ธฐ

function cn() {

  // : className์„ ํ•ฉ์ณ์ฃผ์–ด ์ƒ์œ„์—์„œ className์„ ๋‚ด๋ ค์ฃผ์—ˆ์„ ๋•Œ, ์•ž์— ์ •์˜ํ•œ ์Šคํƒ€์ผ๋ง ๊ฐ’์„ ๋ฎ์–ด์”Œ์šธ ์ˆ˜ ์žˆ๋‹ค

}

๐Ÿ‘‰๐Ÿป ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ชจ์—์„œ ์Šคํƒ€์ผ์„ ๋‚ด๋ ค์„œ ์Šคํƒ€์ผ์„ ์ˆ˜์ •ํ•˜๊ธฐ์— ์šฉ์ดํ•˜๋‹ค.

import { ComponentProps } from "react";
import { cn } from "../utils/style";

type ButtonProps = ComponentProps<"button"> & {
  className?: string;
};

export default function Button({ children, className, ...props }: ButtonProps) {

  return (
    <button
      className={cn(
        "w-fit h-fit bg-black px-4 py-1 rounded-sm border-1 border-black-100",
        className
      )}
      {...props}
    >
      {children}
    </button>
  );
}

์›ฌ๋งŒํ•˜๋ฉด ํ”„๋กœ์ ํŠธ์—๋Š” ์ผ๊ด€๋˜๋Š” ๋””์ž์ธ์ด ์ ์šฉ๋œ๋‹ค.

 

๋”ฐ๋ผ์„œ Button์ด๋ผ๋Š” ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ์— ๋ฒ„ํŠผ Props๋ฅผ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ๋””์ž์ธ์„ ์ž…ํžˆ๊ณ , ์‚ฌ์šฉ์„ ํ•„์š”๋กœ ํ•˜๋Š” ๊ณณ์—์„œ ๊ธฐ์กด button๊ณผ ๋™์ผํ•˜๊ฒŒ <Button></Button>์„ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

import Button from "../components/Button";

export default function Main() {
  
  return (
    <div className="w-full h-full bg-bg-primary flex flex-col items-center justify-center gap-2">
      <Button>Click Me</Button>
      <Button>Double Click Me</Button>
      <Button className="bg-orange-500 border-white">I'm Orange</Button>
    </div>
  );
}

 

๋‹ค์Œ๊ณผ ๊ฐ™์ด <Button></Button> ๋งŒ์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ™œ์šฉํ•˜์—ฌ ์ผ๊ด€์ ์ธ ๋””์ž์ธ์˜ Button์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ˜ธ์ถœํ•  ๋•Œ, className์„ ๋‚ด๋ ค์ฃผ์–ด ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

 

2. ๐Ÿฅ‡ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ (Single Responsibility Principle, SRP)

ํ•œ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•˜๋‚˜์˜ ์—ญํ• ๋งŒ์„ ์ˆ˜ํ–‰ํ•˜๋„๋ก ํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Ÿฌ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  ๊ฒฝ์šฐ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.

๐Ÿ‘‰๐Ÿป ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์›€

 

๋กœ๊ทธ์ธ์„ ํ•˜๊ธฐ ์œ„ํ•œ Form์„ ๋งŒ๋“ค์—ˆ๋‹ค๊ณ  ํ•˜์˜€์„ ๋•Œ,

import Button from "./Button";
import Input from "./Input";

export default function LoginForm() {
  return (
    <form className="flex flex-col justify-center items-center px-5 py-3 gap-5 w-[40rem] h-[25rem] border-1 border-gray-400 rounded-lg bg-black-400 shadow-lg shadow-black-600 ">
      <h1 className="text-2xl font-bold">Login</h1>

      <Input placeholder="ID" />
      <Input placeholder="Password" type="password" />

      <Button type="submit" className="mt-10">
        Sign In
      </Button>
    </form>
  );
}

 

ํผ์— ๋กœ๊ทธ์ธ ํƒ€์ดํ‹€, ์•„์ด๋””, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๋กœ๊ทธ์ธ๋ฒ„ํŠผ.. ๋กœ๊ทธ์ธ ๋‹ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ผ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

 

ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ์€?

๋”ฐ๋กœ Auth๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ

import { ComponentProps } from "react";
import LoginForm from "./LoginForm";
import Button from "./Button";

type AuthProps = ComponentProps<"div">;

export default function Auth({ children, ...props }: AuthProps) {
  return (
    <main
      className="flex flex-col justify-center items-center px-5 py-3 gap-5 w-[40rem] h-[25rem] border-1 border-gray-400 rounded-lg bg-black-400 shadow-lg shadow-black-600 "
      {...props}
    >
      <LoginForm />
      <Button className="bg-gray-400">Sign Up</Button>
    </main>
  );
}

"์ธ์ฆ์—์„œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ๊ณผ ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค."๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•ด์ฃผ์—ˆ๋‹ค.

Auth๋Š” ๋กœ๊ทธ์ธ๊ณผ ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ์˜ ๋‘ ๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ํ•˜์ง€๋งŒ ์ „์ฒด์ ์œผ๋กœ ์ธ์ฆ์ด๋ผ๋Š” ํ•˜๋‚˜์˜ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•œ๋‹ค.

โญ์ปดํฌ๋„ŒํŠธ ๋„ค์ด๋ฐ๋„ ์ค‘์š”ํ•˜๋‹ค.

 

3. ๐Ÿ‘€ ๊ฐ€๋…์„ฑ (Readability)

๐Ÿ‘‰๐Ÿป ์ฝ”๋“œ๊ฐ€ ํ•œ ๋ˆˆ์— ๋“ค์–ด์˜ค๊ณ  ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์กฐ๋ฅผ ์žก๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

๐Ÿ‘‰๐Ÿป ๋„ˆ๋ฌด ๊ธด ์ฝ”๋“œ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด ๊ฐ€๋…์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๋ฏ€๋กœ ์ ์ ˆํ•œ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•ด์•ผํ•œ๋‹ค.

 

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๊ฐ ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์„ ์—ด๋žŒํ–ˆ์„ ๋•Œ, ์–ด๋– ํ•œ ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์žˆ์œผ๋ฉฐ, ์–ด๋– ํ•œ ์—ญํ• ์„ ํ•˜๋Š”์ง€ ์ฝ๊ธฐ ์‰ฝ๋‹ค.

 

โŒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌ๋ฅผ ์•ˆ ํ•œ ๊ฒฝ์šฐ

import { ComponentProps } from "react";
import LoginForm from "./LoginForm";
import Button from "./Button";

type AuthProps = ComponentProps<"div">;

export default function Auth({ children, ...props }: AuthProps) {
  return (
    <main
      className="flex flex-col justify-center items-center px-5 py-3 gap-5 w-[40rem] h-[25rem] border-1 border-gray-400 rounded-lg bg-black-400 shadow-lg shadow-black-600 "
      {...props}
    >
      <form className="flex flex-col justify-center items-center gap-5 w-full">
        <h1 className="text-2xl font-bold">Login</h1>
        <input className="w-full h-10 bg-[#222] px-2 py-1 rounded-xs border-2 border-black-100  focus:border-cyan-600 outline-none" />
        <input className="w-full h-10 bg-[#222] px-2 py-1 rounded-xs border-2 border-black-100  focus:border-cyan-600 outline-none" />
        <button className="w-full h-[3rem] bg-cyan-600 px-4 py-1 rounded-sm border-1 border-gray-400 shadow-lg cursor-pointer hover:brightness-110">
          Sign In
        </button>
      </form>
      <button className="w-full h-[3rem] bg-cyan-600 px-4 py-1 rounded-sm border-1 border-gray-400 shadow-lg cursor-pointer hover:brightness-110">
        Sign Up
      </button>
    </main>
  );
}

๋ฌผ๋ก  ์ธํ’‹, ์ธํ’‹, ๋ฒ„ํŠผ, ๋ฒ„ํŠผ์œผ๋กœ ๋Œ€๋žต ์•Œ์•„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ ๋„ˆ๋ฌด ๋‚œ์žกํ•˜์—ฌ ์ง‘์ค‘์„ ํํŠธ๋Ÿฌ๋œจ๋ฆฐ๋‹ค.

์‹œํ—˜ ๊ธฐ๊ฐ„์— ๋‹ค๋“ค ๋ฐฉ ์ฒญ์†Œํ•˜์ž–์•„๐Ÿ˜‰

 

โญ• ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•œ ๊ฒฝ์šฐ

import Button from "./Button";
import Input from "./Input";

export default function LoginForm() {
  return (
    <form className="flex flex-col justify-center items-center gap-5 w-full">
      <h1 className="text-2xl font-bold">Login</h1>

      <Input placeholder="ID" />
      <Input placeholder="Password" type="password" />

      <Button type="submit" className="mt-10">
        Sign In
      </Button>
    </form>
  );
}

๋” ๊น”๋”ํ•ด์ง€๊ณ , ์–ด๋– ํ•œ ๊ธฐ๋Šฅ์„ ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ง์ ‘ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋กœ ๋“ค์–ด๊ฐ€์„œ ํ™•์ธํ•˜๋ฉด ํ•˜๋‚˜์”ฉ ์ฝ์–ด๋‚˜๊ฐ€๊ธฐ ํŽธ๋ฆฌํ•˜๋‹ค.

๋˜, ํŠน์ • ์ปดํฌ๋„ŒํŠธ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ์ฝ”๋“œ๋งŒ์„ ๋ถ„์„ํ•˜๋ฉด ๋œ๋‹ค.

 

 

4. ๐ŸŽจ UI ์š”์†Œ

๐Ÿ‘‰๐Ÿป ํ•˜๋‚˜์˜ UI ์š”์†Œ๊ฐ€ ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๊ธธ์–ด์ง€๋ฉด ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค.

๐Ÿ‘‰๐Ÿป ex. Form, Table, Card, Dropdown, Sheet์™€ ๊ฐ™์€ UI ์š”์†Œ๋Š” ๋…๋ฆฝ์ ์ธ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

import Button from "./Button";

type CardProps = {
  imageSrc: string;
  onhandlePurchase: () => void;
};

export default function Card({ imageSrc, onhandlePurchase }: CardProps) {
  return (
    <main className="w-50 h-70 bg-bg-primary flex flex-col items-center justify-between bg-black-100 rounded-lg py-3 px-3  gap-2">
      <img
        className="w-full h-full flex flex-1 rounded-lg items-center justify-center bg-white/30 text-black"
        src={imageSrc}
        alt="product"
      />
      <Button onClick={onhandlePurchase}>Purchase</Button>
    </main>
  );
}

 

 

 

 

5. ๐Ÿค’ ์ƒํƒœ์™€ ๋ผ์ดํ”„์‚ฌ์ดํด (State and LifeCycle)

์ƒํƒœ๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ์ดํ„ฐ -> ๋ณ€๊ฒฝ๋˜๋ฉด ๋ฆฌ๋ Œ๋”๋ง ๋ฐœ์ƒ

๋ผ์ดํ”„์‚ฌ์ดํด์€ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ, ์ œ๊ฑฐ ๋  ๋•Œ๋ฅผ ์˜๋ฏธ

 

๋”ฐ๋ผ์„œ, ๊ฐœ๋ฐœ ์‹œ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋“ค์ด ์„ฑ๋Šฅ๊ณผ ๋™์ž‘์— ์–ด๋–ป๊ฒŒ ๋ฏธ์น˜๋ฉฐ, React Developer Tool ์™€ ๊ฐ™์€ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์ง€๋Š” ์•Š์€์ง€ ํ™•์ธํ•œ๋‹ค.

 

React Developer Tools - Chrome ์›น ์Šคํ† ์–ด

Adds React debugging tools to the Chrome Developer Tools. Created from revision 44c3d3d665 on 2/7/2025.

chromewebstore.google.com

 


๐Ÿ™ ์‘์ง‘๋„

์‘์ง‘๋„๋ž€, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•˜๋‚˜์˜ ์ฑ…์ž„ ๋˜๋Š” ๋ชฉ์ (SRP)์„ ์ž˜ ์ˆ˜ํ–‰ํ•˜๊ณ  ์žˆ๋Š”๊ฐ€? ๋ฅผ ๋งํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ, ์ข‹์€ ์‘์ง‘๋„๋ž€ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ช…ํ™•ํ•œ ๊ธฐ๋Šฅ ํ•˜๋‚˜๋งŒ์„ ๋‹ด๋‹นํ•œ๋‹ค.

ex)

โญ• UserProfileCard: ์œ ์ € ์ •๋ณด๋ฅผ ์นด๋“œ ํ˜•ํƒœ๋กœ ๋ณด์—ฌ์ฃผ๋Š” UI ์ปดํฌ๋„ŒํŠธ

โŒ Dashboard: ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์œ ์ € ๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜ค๊ณ , ์ฐจํŠธ๋ฅผ ๊ทธ๋ ค์ฃผ๊ณ , ์•Œ๋ฆผ์„ ๋„์šฐ์ค€๋‹ค.

 

// โŒ ์•ˆ ์ข‹์€ ์˜ˆ์‹œ
const Dashboard = () => {
  return (
    <div>
      <UserList/>
      <SalesChart/>
      <NotificationPanel/>
    </div>
  ) 
}

// โญ• ์ข‹์€ ์˜ˆ์‹œ
const SalesChart = ({data: SalesData}) => {

  return <Chart data={data}/>
}

 

์œ„์ฒ˜๋Ÿผ ๋Œ€์‹œ๋ณด๋“œ๋Š” ๋ญ”๊ฐ€ ์ „์ฒด์ ์ธ ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๋ฉด์„œ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋Š” ๊ฒƒ์œผ๋กœ ํŒŒ์•…๋œ๋‹ค. ํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ์ค€์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

๋ ˆ์ด์•„์›ƒ ๋ฐฐ์น˜์˜ ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์ด ์ ๋‹นํ•˜๋‹ค.

๐Ÿ’กTip. ์ปดํฌ๋„ŒํŠธ ์ด๋ฆ„์„ ๋ณด๊ณ  "์ด๊ฒŒ ๋ฌด์Šจ ์—ญํ• ์„ ํ•˜๋Š”์ง€" ๋ฐ”๋กœ ์•Œ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

 

๐Ÿ” ๊ฒฐํ•ฉ๋„

๊ฒฐํ•ฉ๋„๋ž€, ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ ๋ชจ๋“ˆ๊ณผ ์–ผ๋งˆ๋‚˜ ๊ฐ•ํ•˜๊ฒŒ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š”๊ฐ€?

๋‚ฎ์€ ๊ฒฐํ•ฉ๋„๋Š” props๋กœ๋งŒ ํ•„์š”ํ•œ ์ตœ์†Œ ์ •๋ณด๋งŒ ์ฃผ๊ณ  ๋ฐ›์œผ๋ฉฐ ๋™์ž‘

๋†’์€ ๊ฒฐํ•ฉ๋„๋Š” ๋ถ€๋ชจ ์ƒํƒœ์— ๊ณผํ•˜๊ฒŒ ์˜์กดํ•˜๊ฑฐ๋‚˜, ๋‚ด๋ถ€ ๋กœ์ง์ด ์ƒ์œ„ ๊ตฌ์กฐ์— ์กด์žฌํ•œ๋‹ค.

 

// โŒ ์•ˆ ์ข‹์€ ์˜ˆ์‹œ
const UserCard = () => {
  const user = globalStore.users[0];
  return <div>{user.name}</div>;
}

// โญ• ์ข‹์€ ์˜ˆ์‹œ
const UserCard = ({user}) => {
  return <div>{user.name}</div>
}

 

์ƒ๊ฐ์„ ํ•ด๋ณด์ž.

์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ด์œ ๋Š” ์—ฌ๋Ÿฌ ๊ตฐ๋ฐ์—์„œ ๋ถˆ๋Ÿฌ์™€์„œ ๋‚ด ๋งˆ์Œ๋Œ€๋กœ ๋ฐ”๊ฟ”์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, Button์„ ๋งŒ๋“ค์–ด์„œ ํ•ด๋‹น ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ž‘๋™ํ•  onClick() ์ด๋ฒคํŠธ๋ฅผ props๋กœ ๋ฐ›์•„์™€์„œ ์ผ๋ฐ˜ ๋ฒ„ํŠผ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์—์„œ ๋ง›๋ณ„๋กœ ์„ค์ •ํ•œ๋‹ค.

์ด ์ฒ˜๋Ÿผ, ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ๋™์ž‘์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ props๋ฅผ ํ†ตํ•˜์—ฌ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ˜๋‹ค.

 

์œ„ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด UserCard์˜ ๋‚˜์œ ์˜ˆ์‹œ๋Š” ์™ธ๋ถ€์—์„œ์˜ ์ƒํƒœ์— ๋ฌถ์—ฌ์žˆ์–ด ์žฌ์‚ฌ์šฉ๋ฐ ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋ ค์›Œ์ง„๋‹ค.

 

 

โœจ ๊ฒฐ๋ก 

โฌ†๏ธ ์‘์ง‘๋„๋Š” ํฌ๊ฒŒ 

โฌ‡๏ธ ๊ฒฐํ•ฉ๋„๋Š” ์ž‘๊ฒŒ