React : Props

<angeLog/>ยท2024๋…„ 2์›” 19์ผ

REACT

๋ชฉ๋ก ๋ณด๊ธฐ
6/25
post-thumbnail

๐Ÿ’ก๋…ธ๋งˆ๋“œ์ฝ”๋” ๋‹ˆ๊ผฌ์Œค์˜ ๊ฐ•์˜๋ฅผ ๋ณด๋ฉฐ ๊ณต๋ถ€ํ•˜๋Š” ์‹œ๋ฆฌ์ฆˆ์ž…๋‹ˆ๋‹ค.

props
๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ž์‹์ปดํฌ๋„ŒํŠธ์— data๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•.

"save Changes"๊ธฐ๋Šฅ์˜ btn๊ณผ "confirm"๊ธฐ๋Šฅ์„ ํ•˜๋Š” btn์„ ๋งŒ๋“ ๋‹ค๊ณ  ํ•ด๋ณด์ž.

function SaveBtn() {
  return <button>save Changes</button>;
}
function ConfirmBtn() {
  return <button>Confirm</button>;
}
function App() {
  return (
    <div>
      <SaveBtn />
      <ConfirmBtn />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

JSX์˜ Style Property(์†์„ฑ)

jsx์—์„œ style์†์„ฑ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” {{์ค‘๊ด„ํ˜ธ 2๊ฐœ}}์•ˆ์—์„œ camelCase๋กœ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.

function SaveBtn() {
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
      }}
      >
      save Changes
    </button>
  );
}
function ConfirmBtn() {
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
      }}
      >
      Confirm
    </button>
  );
}
function App() {
  return (
    <div>
      <SaveBtn />
      <ConfirmBtn />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

์˜ˆ์˜๊ฒŒ ๋˜๊ธด ํ–ˆ๋Š”๋ฐ ์ฝ”๋“œ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ์–ด์ง„๋‹ค.
๊ณตํ†ต๋œ ์Šคํƒ€์ผ์„ ๊ฐ€์ง„ ํ•œ๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์žฌ์‚ฌ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

//Btn์ด๋ผ๋Š” component๋ฅผ ์ƒ์„ฑํ•˜๊ณ  style์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””์ž์ธํ•œ๋‹ค.
function Btn() {
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
      }}
      ></button>
  );
}

function App() {
  return (
    <div>
      //์ƒ์„ฑํ•œ Btn ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ตœ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์ธ App์— render.
      <Btn />
      <Btn />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

๋™์ผํ•œ ์Šคํƒ€์ผ์˜ ๋ฒ„ํŠผ ๋‘๊ฐœ๊ฐ€ ๋งŒ๋“ค์–ด ์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
๊ทธ๋ ‡๋‹ค๋ฉด ๊ฐ ๋ฒ„ํŠผ์˜ ์ด๋ฆ„์€ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ ํ•  ์ˆ˜ ์žˆ์„๊นŒ?

Props ์‚ฌ์šฉํ•˜๊ธฐ

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์ธ App์—์„œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์ธ Btn์— ๊ฐ๊ฐ banana, big์ด๋ผ๋Š” ์ •๋ณด๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

//๋ถ€๋ชจ์š”์†Œ App
function App() {
  return (
    <div>
      //App์— render๋œ ์ž์‹์š”์†Œ Btn.
      //banana, big์€ ๋ถ€๋ชจ์š”์†Œ App์ด ์ž์‹์š”์†Œ์ธ Btn์— ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ์ •๋ณด.
      <Btn banana="save Changes" big={true} />
      <Btn banana="confirm" big={false} />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ render๋œ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ์ •๋ณด๋ฅผ ์ž‘์„ฑํ•˜๋ฉด, props๋ฅผ ํ†ตํ•ด ์ž์‹์š”์†Œ์— ํ•ด๋‹น ์ •๋ณด๊ฐ€ ์ „๋‹ฌ๋œ๋‹ค.
props๋Š” Btn ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๋Š” ์ฒซ๋ฒˆ์งธ์ด์ž ์œ ์ผํ•œ argument(์ „๋‹ฌ์ธ์ž)์ด๋‹ค.

function Btn(props) {
  console.log(props);
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
        fontSize: props.big ? 24 : 16,
      }}
      >
      {props.banana}
    </button>
  );
}

props๋Š” ๊ฐ์ฒด๋กœ ๋“ค์–ด์˜ค๊ธฐ ๋•Œ๋ฌธ์—, props์˜ key์— ๋”ฐ๋ฅธ value๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด props.key๋กœ ๊บผ๋‚ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

์ „์ฒด์ฝ”๋“œ

function Btn(props) {
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
        fontSize: props.big ? 24 : 16,
      }}
      >
      {props.banana}
    </button>
  );
}
function App() {
  return (
    <div>
      <Btn banana="save Changes" big={true} />
      <Btn banana="confirm" big={false} />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

Short Cut
props.key๋กœ ์ •๋ณด๋ฅผ ๊บผ๋‚ด๋Š” ๊ฒƒ์ด ์‹ซ๋‹ค๋ฉด props๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊บผ๋‚ด์„œ ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค.

function Btn({ banana, big }) {
  return (
    <button
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
        fontSize: big ? 24 : 16,
      }}
      >
      {banana}
    </button>
  );
}
function App() {
  return (
    <div>
      <Btn banana="save Changes" big={true} />
      <Btn banana="confirm" big={false} />
    </div>
  );
}
const root = document.getElementById("root");
ReactDOM.render(<App />, root);

ํ•˜์ง€๋งŒ ๋‚˜๋Š” shortCut๋ณด๋‹ค๋Š” props๊ฐ์ฒด๋กœ ๋„˜๊ธฐ๊ณ  ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ๋” ์ข‹๋‹ค.

props, ํ•จ์ˆ˜๋„ ์ „๋‹ฌ ํ•  ์ˆ˜ ์žˆ์–ด!

text, boolean ๋ง๊ณ ๋„ ํ•จ์ˆ˜๋„ props๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

function App() {
  // ์ดˆ๊ธฐ๊ฐ’์ด "save Changes"์ธ useState ์ƒ์„ฑ.
  const [value, setValue] = React.useState("save Changes");
  //changeValue๊ฐ€ ์–ด๋–ค์ž‘๋™์„ ํ•ด์•ผํ• ์ง€ ์ ์–ด์ฃผ๊ณ ,
  const changeValue = () => {
    setValue("revert Changes");
  };
  return (
    <div>
      // banana๋ผ๋Š” ์ธ์ž์—๋Š” value,
      //potato๋ผ๋Š” ์ธ์ž์•ˆ์— changeValue๋ผ๋Š” ์ „๋‹ฌ์š”์†Œ๋ฅผ ์ ์–ด์ค€๋‹ค.
      <Btn banana={value} popato={changeValue} />
      <Btn banana="confirm" />
    </div>
  );
}

์—ฌ๊ธฐ์—์„œ popato๊ฐ€ ๋ฐ”๋กœ ์ž์‹์š”์†Œ์—๊ฒŒ ์ „๋‹ฌ๋˜๋Š” event์ธ๋ฐ ์ด๊ฒƒ์ด eventListner๋Š” ์•„๋‹ˆ๋‹ค.
์ž‘๋™ํ•ด์•ผํ•˜๋Š” event๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” argument์ „๋‹ฌ์ธ์ž ์ผ ๋ฟ์ด๋‹ค.

//App์˜ ์ž์‹์š”์†Œ์ธ Btn์— App์ด ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” potato๋ฅผ props๋กœ ์ „๋‹ฌํ•˜๊ณ 
function Btn({ banana, popato }) {
  return (
    <button
      //eventListenr์ธ onClick์— popato๋ฅผ ๋‹ด์•„์ค€๋‹ค.
      onClick={popato}
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
        fontSize: 16,
      }}
      >
      {banana}
    </button>
  );
}

Props ์™œ ์“ด๋‹ค๊ตฌ?

props = ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š” ๋ฐฉ์‹.
๋ถ€๋ชจ์— props๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ž์‹ ์ปดํฌ๋„ŒํŠธ(ํ•จ์ˆ˜)์˜ ์ธ์ž๋กœ ๊ฐ์ฒด๊ฐ€ ๋“ค์–ด๊ฐ€๊ฒŒ ๋จ.
ํ•˜๋‚˜์˜ ๋ฒ„ํŠผ์„ ๋งŒ๋“ค์–ด์„œ props๋ฅผ ์ด์šฉํ•ด ๋ฒ„ํŠผ์˜ ์Šคํƒ€์ผ์„ ๊ด€๋ฆฌํ•ด์„œ ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ๋จ.

๊ทธ๋Ÿฐ๋ฐ ์ฝ˜์†”์„ ์ฐ์–ด๋ณด๋ฉด ์ข€ ์ด์ƒํ•œ ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
react์—์„œ๋Š” ๋ณ€๊ฒฝํ•œ state๋งŒ updateํ•œ๋‹ค๊ณ  ๋ฐฐ์› ๋Š”๋ฐ ๊ทธ๋ ‡๋‹ค๋ฉด ์ฝ˜์†”๋„ ๋ณ€๊ฒฝ๋œ state๋งŒ ์ฐํ˜€์•ผํ•˜๋Š” ๊ฒƒ ์•„๋‹๊นŒ? ํ•˜์ง€๋งŒ ์ด๊ฒƒ์€ ๋‹น์—ฐํ•˜๋‹ค. ๋ถ€๋ชจ์š”์†Œ์ธ App์˜ ๊ธฐ์ค€์œผ๋กœ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋œ๋‹ค. Btn์„ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๋ถ€๋ชจ์š”์†ŒApp์€ ์ž์‹์š”์†Œ์ธ Btn์— ์˜ํ•ด ๋ณ€ํ™”๋ฅผ ๊ฒช๊ฒŒ ๋˜๊ธฐ๋•Œ๋ฌธ์— ์ „์ฒด๊ฐ€ ๋‹ค์‹œ ๊ทธ๋ ค์ง€๊ธฐ ๋•Œ๋ฌธ์— console๋˜ํ•œ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ banana๊นŒ์ง€ ์ฐํžˆ๋Š” ๊ฒƒ์ด๋‹ค.

๊ตณ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ state๊นŒ์ง€ ๋‹ค์‹œ ๊ทธ๋ ค์ค˜์•ผํ•ด?
react๋Š” ๊ทธ ๋ถ€๋ถ„๋˜ํ•œ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณด์™„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์‹œํ•œ๋‹ค.

React.memo()

React.memo()
state๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” component๋Š” ๋‹ค์‹œ ๊ทธ๋ ค์ง€์ง€ ์•Š๋„๋ก react์—๊ฒŒ ๊ธฐ์–ต(Memorize)ํ•˜๋„๋ก ๋ช…๋ นํ•˜๋Š” react Hook.

์ปดํฌ๋„ŒํŠธ Btn์„ React.memo()๋ฅผ ์ด์šฉํ•ด MemorizeBtn๋ผ๋Š” ์ด๋ฆ„์˜ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

function Btn({ banana, popato }) {
  console.log(banana, "render๋์Œ");
  return (
    <button
      onClick={popato}
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "19px 20px",
        border: "none",
        borderRadius: 10,
        fontSize: 16,
      }}
      >
      {banana}
    </button>
  );
}
const MemorizeBtn = React.memo(Btn);

๋ถ€๋ชจ์š”์†ŒApp์•ˆ์˜ ์ž์‹์š”์†ŒBtn๋˜ํ•œ ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ์ธ MemorizeBtn๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

function App() {
  const [value, setValue] = React.useState("save Changes");
  const changeValue = () => {
    setValue("revert Changes");
  };
  return (
    <div>
      <MemorizeBtn banana={value} popato={changeValue} />
      <MemorizeBtn banana="confirm" />
    </div>
  );
}

๋ณ€๊ฒฝ๋œ state๋งŒ console์— ์ฐํžŒ๋‹ค.

propTypes

propTypes๋Š” react๊ฐ€ ์ œ๊ณตํ•˜๋Š” props์˜ type์„ ์ฒดํฌํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

//์Šคํฌ๋ฆฝํŠธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€
<script src="https://unpkg.com/prop-types@15.8.1/prop-types.js"></script>
function App() {
  const [value, setValue] = React.useState("save Changes");
  const changeValue = () => {
    setValue("revert Changes");
  };
  return (
    <div>
      //์ •์ƒ์ ์ธ props๊ฐ€ ๋‹ด๊ธด Btn
      <Btn banana={value} popato={changeValue} fontSize={24} />
      
      //ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด Btn์˜ props๋“ค์„ ์ž˜๋ชป๋œ ํƒ€์ž…์œผ๋กœ ๋„ฃ์–ด๋ณด์•˜๋‹ค.
      <Btn banana={14} fontSize={"Continue"}/>
    </div>
  );
}

๋ฌธ์ œ ์—†์–ด๋ณด์ธ๋‹ค. ํ•˜์ง€๋งŒ ๋ถ„๋ช…ํžˆ ์ž˜๋ชป๋œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.
fontSize์˜ ํƒ€์ž…์€ number์ด๊ณ , banana๋Š” string์ธ ๊ฒƒ์„ ์šฐ๋ฆฌ๋Š” ์•Œ ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ react๋Š” ๊ทธ๊ฒƒ์„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— propTypes์„ ์‚ฌ์šฉํ•ด Props๋กœ ์ „๋‹ฌํ•˜๋Š” state์˜ type์ด ๋ฌด์—‡์ธ์ง€ ํ™•์ธํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์•ผํ•œ๋‹ค.

Btn.propTypes = {
  banana: PropTypes.string,
  fontSize: PropTypes.number,
};

type์— ๋งž์ง€ ์•Š๋Š” ๊ฐ’์„ ๋ณด๋‚ด๊ณ  ์žˆ๋‹ค๊ณ  ๊ฒฝ๊ณ ํ•˜๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.
์–ด๋””์˜ ์–ด๋А ๋ถ€๋ถ„์ด ๋ฌธ์ œ์ธ์ง€ ์ฝ• ์ง‘์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํ™•์ธ ํ›„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘‰๐ŸปpropTypes๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค

profile
์ผ๋‹จ ํ•ด๋ณผ๊ฒŒ์š”!โœ๐Ÿป

0๊ฐœ์˜ ๋Œ“๊ธ€