Sally-Day
BlogAbout

Describing the UI (2)

2023.02.10

React Docs

๐ŸŒ Describing the UI

Passing Props to Component


  • Specifying a default value for a prop
    prop์— ๊ธฐ๋ณธ ๊ฐ’์„ ์„ค์ •ํ•ด๋‘๊ณ , ์•„๋ฌด ๊ฐ’์„ ์ „๋‹ฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ธฐ๋ณธ ๊ฐ’์ด ์„ค์ •๋œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ null ๋˜๋Š” 0์„ ์ „๋‹ฌํ•˜๋ฉด ๊ธฐ๋ณธ ๊ฐ’์ด ์‚ฌ์šฉ ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • Forwarding props with the JSX spread syntax
    Spread syntax๋กœ props๋ฅผ ์ „๋‹ฌํ•˜๋ฉด ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ „๋‹ฌ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋ชจ๋“  ๊ณณ์—์„œ ์•„๋ž˜์™€ ์‚ฌ์šฉํ•˜๋ฉด ๋ญ”๊ฐ€ ์ž˜๋ชป๋œ ๊ฒƒ์ด๋‹ˆ ์ œํ•œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ž.
    function Profile(props) {
      return (
        <div className="card">
          <Avatar {...props} />
        </div>
      );
    }
  • How props change over time
    ์ปดํฌ๋„ŒํŠธ๋Š” ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ๋‹ค๋ฅธ props๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. props๋Š” ํ•ญ์ƒ staticํ•˜์ง„ ์•Š๋‹ค!

    A component may receive different props over time. Props are not always static!

Props๋Š” ์ฒ˜์Œ์—๋งŒ ์•„๋‹ˆ๋ผ ๋ชจ๋“  ์‹œ์ ์—์„œ ์ปดํฌ๋„ŒํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜์˜ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ props๋Š” ๋ถˆ๋ณ€ํ•œ๋‹ค. ์ปดํฌ๋„ŒํŠธ๊ฐ€ props๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๋•Œ๋Š” ์ปดํฌ๋„ŒํŠธ์— ์ƒˆ๋กœ์šด props๋ฅผ ์ „๋‹ฌํ•˜๋„๋ก ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ด์ „ props๋Š” ๋ฒ„๋ ค์ง€๊ณ , ๊ฒฐ๊ตญ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ props๊ฐ€ ๊ฐ€์ ธ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•œ๋‹ค.

props๋ฅผ ๋ฐ”๊พธ๋ ค๊ณ  ํ•˜์ง€๋ง์ž. ์ƒํ˜ธ์ž‘์šฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” state๋ฅผ ์“ฐ๋ฉด ๋œ๋‹ค.

Conditional Rendering


  • Deep Dive: Are these two examples fully equivalent?
    ex. 1

    if (isPacked) {
      return <li className="item">{name} โœ”</li>;
    }
    return <li className="item">{name}</li>;

    ex. 2

    return <li className="item">{isPacked ? name + ' โœ”' : name}</li>;

    JSX ์š”์†Œ๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ์•„๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด JSX ์š”์†Œ๋Š” ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ๋ณด์œ ํ•˜์ง€ ์•Š์•˜๊ณ , ์‹ค์ œ DOM ๋…ธ๋“œ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ๋‘ ์˜ˆ์‹œ๋Š” ์™„์ „ํžˆ ๋™์ผํ•˜๋‹ค.

  • Logical AND operator &&
    ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž &&๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์กฐ๊ฑด์ด true์ผ ๋•Œ๋Š” ์ผ๋ถ€ JSX๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š”๋‹ค.

    ๐ŸŒšย && ์™ผ์ชฝ์— ์ˆซ์ž๋ฅผ ๋„ฃ์ง€ ๋ง์ž. ์กฐ๊ฑด์„ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์™ผ์ชฝ์„ ์ž๋™์œผ๋กœ boolean๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์–ด๋–ค ๊ฐ’์ด 0์ด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ธฐ ์‰ฝ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” 0 ๊ทธ ์ž์ฒด๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์™ผ์ชฝ์€ ๊ฐ’์ด boolean์ด ๋˜์–ด์•ผ ํ•œ๋‹ค.

Rendering Lists


  • Keeping list items in order withย key
    ํ‚ค๋ฅผ ์•ˆ์“ฐ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ Warning์ด ๋‚˜์˜จ๋‹ค.

    Each child in a list should have a unique โ€œkeyโ€ prop.

uniqueํ•œ string์ด๋‚˜ number ๊ฐ’์„ ์‚ฌ์šฉํ•ด์„œ ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ ์•„์ดํ…œ์— key๋ฅผ ์ฃผ๋ฉด ํ•ด๊ฒฐ๋œ๋‹ค.

<li key={person.id}>...</li>

key๋Š” React์—๊ฒŒ ๊ฐ ์ปดํฌ๋„ŒํŠธ์— ํ•ด๋‹นํ•˜๋Š” ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ์„ ์•Œ๋ ค์ฃผ์–ด ๋‚˜์ค‘์— ๋งค์น˜์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๋ฆฌ์ŠคํŠธ ์•„์ดํ…œ์ด ์ •๋ ฌ๋˜๊ฑฐ๋‚˜ ์‚ฝ์ž…๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋˜๋Š” ๋“ฑ ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ์ƒ๊ฒผ์„ ๋•Œ, key๊ฐ€ React์—๊ฒŒ ์ •ํ™•ํžˆ ๋ฌด์Šจ์ผ์ด ์ผ์–ด๋‚ฌ๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ  DOM ํŠธ๋ฆฌ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์— ๋„์›€์„ ์ค€๋‹ค.

  • Deep Dive: Displaying several DOM nodes for each list item

<>โ€ฆ</> Fragment ๊ตฌ๋ฌธ์œผ๋กœ๋Š” ํ‚ค๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, <div>๋‚˜ <Fragment>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

const listItems = people.map(person => (
  <Fragment key={person.id}>
    <h1>{person.name}</h1>
    <p>{person.bio}</p>
  </Fragment>
));
  • Where to get yourย key

    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ฐ์ดํ„ฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ key๋‚˜ ID๋ฅผ ์“ฐ๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ unique ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
    • ๋กœ์ปฌ์—์„œ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ์ปฌ์—์„œ ์ƒ์„ฑ๋˜๊ณ  ์œ ์ง€๋˜๋Š” ๊ฒฝ์šฐ, incrementing counter์ธ crypto.randomUUID() ๋˜๋Š”ย uuid ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • Rules of keys

    • key๋Š” ํ˜•์ œ ๊ฐ„์— ๊ณ ์œ ํ•ด์•ผ ํ•œ๋‹ค. (๋‹จ, ๋‹ค๋ฅธ ๋ฐฐ์—ด์—์„œ๋Š” ๊ฐ™์€ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.)
    • key๋Š” ๋ณ€๊ฒฝ๋˜์–ด์„œ ์•ˆ๋˜๊ณ , key์˜ ๋ชฉ์ ์— ์–ด๊ธ‹๋‚˜๋ฉด ์•ˆ๋œ๋‹ค. ๋ Œ๋”๋งํ•˜๋Š” ๋™์•ˆ ์ƒ์„ฑํ•˜๋ฉด ์•ˆ๋œ๋‹ค.
  • Why does React need keys?
    ํด๋”์˜ ํŒŒ์ผ ์ด๋ฆ„๊ณผ ๋ฐฐ์—ด์—์„œ JSX key๋Š” ๋น„์Šทํ•œ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ˜•์ œ ๊ฐ„์— ์•„์ดํ…œ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

    ๐ŸŒš ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ key๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ง์ž. ๋ฐฐ์—ด์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋ฉด ์ธ๋ฑ์Šค๊ฐ€ ๋ณ€ํ•˜๊ณ , ์ด๋Š” ํ˜ผ๋ž€์Šค๋Ÿฌ์šธ ์ˆ˜ ์žˆ๋‹ค. ๋˜, key๋ฅผ ์ฆ‰์„์—์„œ ์ƒ์„ฑํ•˜์ง€ ๋ง์ž. ์ฆ‰์„์œผ๋กœ ์ƒ์„ฑํ•˜๋ฉด ๋ Œ๋”๋ง ์‹œ์— ํ‚ค๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์•„ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์™€ DOM์ด ๋งค๋ฒˆ ๋‹ค์‹œ ์ƒ์„ฑ๋œ๋‹ค.

Keeping Components Pure


  • Purity: Components as formulas

    Pure function์€ ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์„ฑ์ด ์žˆ๋‹ค.

    • ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ์ด๋ฏธ ์กด์žฌํ•œ ๊ฐ์ฒด๋‚˜ ๋ณ€์ˆ˜๋ฅผ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค.

    • ๊ฐ™์€ ์ž…๋ ฅ์„ ํ•˜๋ฉด ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์•ผ ํ•œ๋‹ค. React์—์„œ๋Š” ์œ„์˜ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๋Š” pure function์ด๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์ž‘์„ฑํ•œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํ•ญ์ƒ ๊ฐ™์€ JSX๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ๋งˆ์น˜ ์ˆ˜ํ•™ ๊ณต์‹์ฒ˜๋Ÿผ ๋ง์ด๋‹ค.


Pure function์˜ ๊ทœ์น™์„ ์–ด๊ธด ์˜ˆ์‹œ๋ฅผ ๋ณด์ž. ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘์ ์œผ๋กœ ๋ฐ”๊พธ๋ฉด์„œ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•ด๋„ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

Pure function์œผ๋กœ ๋ฐ”๊พธ๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค. guest๋ผ๋Š” prop์—๋งŒ ์˜์กดํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}
  • Deep Dive: Detecting impure calculations with StrictMode
    React๋Š” ๊ฐœ๋ฐœ ์ค‘์— ๊ฐ ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋ฅผ 2๋ฒˆ ํ˜ธ์ถœํ•˜๋Š” Strict Mode๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด๋Š” ํ•จ์ˆ˜๊ฐ€ Pure function์˜ ๊ทœ์น™์„ ์–ด๊ฒผ๋Š”์ง€ ์ฐพ๋Š” ๊ฒƒ์„ ๋„์™€์ค€๋‹ค. Strict Mode๋Š” ๋ฐฐํฌ์— ์•„๋ฌด ์˜ํ–ฅ์ด ์—†๋‹ค. ๊ทธ๋ž˜์„œ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•œ ์„œ๋น„์Šค๋ฅผ ๋Š๋ฆฌ๊ฒŒ ๋งŒ๋“ค์ง„ ์•Š๋Š”๋‹ค.

  • Local mutation: Your componentโ€™s little secret
    ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ณ€์ˆ˜๋ฅผ ๋ Œ๋”๋ง ์ค‘์— ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ mutation์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
    Pure function์€ ํ•จ์ˆ˜ ๋ฒ”์œ„ ๋ฐ–์˜ ๋ณ€์ˆ˜๋‚˜ ํ˜ธ์ถœ ์ „์— ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด ๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ๋ฌธ์ œ๋˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋‚ด๋ถ€์—์„œ ๋™์ผํ•œ ๋ Œ๋”๋ง ์ค‘์— ์ƒ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    function Cup({ guest }) {
      return <h2>Tea cup for guest #{guest}</h2>;
    }
    
    export default function TeaGathering() {
      let cups = [];
      for (let i = 1; i <= 12; i++) {
        cups.push(<Cup key={i} guest={i} />);
      }
      return cups;
    }
  • Where youย canย cause side effects
    ํ™”๋ฉด ์—…๋ฐ์ดํŠธ, ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ๋“ฑ ์—ฌ๋Ÿฌ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ side effects๋ผ๊ณ  ํ•œ๋‹ค. ๋ Œ๋”๋ง ๋™์•ˆ์— ์ผ์–ด๋‚˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ side์—์„œ ์ผ์–ด๋‚œ๋‹ค. React์—์„œ side effects๋Š” ์ฃผ๋กœ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์— ์†ํ•ด์žˆ๋‹ค. ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์ •์˜๋˜์–ด ์žˆ์–ด๋„ ๋ Œ๋”๋ง ๋™์•ˆ ์‹คํ–‰๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ pureํ•˜๊ฒŒ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

    • Deep Dive: Why does React care about purity?
      1. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ(์˜ˆ: ์„œ๋ฒ„)์—์„œ ์‹คํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ™์€ ์ž…๋ ฅ์—์„œ๋Š” ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์€ ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
      2. ์ž…๋ ฅ์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์„ ํ•˜์ง€ ์•Š์•„ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋  ์ˆ˜ ์žˆ๋‹ค. Pure function์€ ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ ์บ์‹œํ•˜๊ธฐ์— ์•ˆ์ „ํ•˜๋‹ค.
      3. ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ๋ฅผ ๋ Œ๋”๋งํ•˜๋‹ค ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๋‹ค์‹œ ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์–ธ์ œ๋“  ๊ณ„์‚ฐ์„ ์ค‘๋‹จํ•ด๋„ pure function์˜ ํŠน์ง• ๋•๋ถ„์— ์•ˆ์ „ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

References


Copyright โ“’ 2023 Dayeon Won All rights reserved.
Powered By gatsby-tech-blog