[React] Describing the UI

2023. 9. 27. 23:36ใ†React

728x90
๋ฐ˜์‘ํ˜•

๐Ÿ“„ Docs

2023๋…„์— ๋ฆฌ๋‰ด์–ผ๋œ ๋ฆฌ์•กํŠธ ๊ณต์‹ ๋ฌธ์„œ์˜ "Describing the UI" ๋‚ด์šฉ์ด๋‹ค.

๐Ÿ“š You will learn

  • React Component
  • import / export
  • JSX
  • props
  • ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง
  • ๋ชฉ๋ก ๋ Œ๋”๋ง
  • ์ปดํฌ๋„ŒํŠธ ์ˆœ์ˆ˜์„ฑ ์œ ์ง€

1. React Component

1-1. ์ปดํฌ๋„ŒํŠธ: UI ๊ตฌ์„ฑ ์š”์†Œ

  • ๋ฆฌ์•กํŠธ๋Š” markup, CSS, JS๋ฅผ ์‚ฌ์šฉ์ž ์ •์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ฒฐํ•ฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋ฉฐ, ์ด๋Š” ์•ฑ์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ UI ์š”์†Œ๊ฐ€ ๋œ๋‹ค.

1-2. ์ปดํฌ๋„ŒํŠธ ์ค‘์ฒฉ

  • ์ปดํฌ๋„ŒํŠธ๋Š” ์ผ๋ฐ˜ JS ํ•จ์ˆ˜์ด๋ฏ€๋กœ ํ•œ ํŒŒ์ผ์— ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•  ์ˆ˜๋Š” ์žˆ์ง€๋งŒ, ์•„๋ž˜์ฒ˜๋Ÿผ ์ •์˜๋ฅผ ์ค‘์ฒฉํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค!!
export default function Gallery() {
  // ๐Ÿ”ด Never define a component inside another component!
  function Profile() {
    // ...
  }
  // ...
}
  • ์•„๋ž˜์ฒ˜๋Ÿผ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์—์„œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค.
export default function Gallery() {
  // ...
}

// โœ… Declare components at the top level
function Profile() {
  // ...
}

2. import / export

2-1. root ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ

  • Create React App์—์„œ๋Š” ์•ฑ ์ „์ฒด๊ฐ€ root ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ์ธ src/App.js์—์„œ ์‹คํ–‰๋œ๋‹ค. (์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํŒŒ์ผ์— ์œ„์น˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.)

๋ชจ๋“ˆ์„ฑ์„ ๊ฐ•ํ™”ํ•˜๊ณ  ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ
์ปดํฌ๋„ŒํŠธ๋ฅผ root ์ปดํฌ๋„ŒํŠธ ํŒŒ์ผ ๋ฐ–์œผ๋กœ ์˜ฎ๊ธฐ๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

2-2. import / export

1) ์ปดํฌ๋„ŒํŠธ ์ด๋™์‹œํ‚ค๊ธฐ

  • ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„ฃ์„ JS ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.
  • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ exportํ•œ๋‹ค.
  • ์‚ฌ์šฉํ•  ํŒŒ์ผ์—์„œ importํ•œ๋‹ค.

2) default export VS named export

  • ํ•œ ํŒŒ์ผ์—์„œ default export๋Š” ํ•˜๋‚˜๋งŒ ๊ฐ€๋Šฅ!
    named export๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ๊ฐ€๋Šฅ!
  • export ๋ฐฉ์‹์— ๋”ฐ๋ผ import ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์ง„๋‹ค.
  • default import๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
  • named import๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด๋ฆ„์ด ๊ฐ™์•„์•ผ๋งŒ ํ•œ๋‹ค.
Syntax Export Import
Default export default function Button() {} import Button from './Button.js';
Named export function Button() {} import {Button} from './Button.js';

3. JSX

3-1. ๋ Œ๋”๋ง ๋กœ์ง๊ณผ ๋งˆํฌ์—…์ด ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ์— ์œ„์น˜ํ•˜๊ฒŒ ๋œ ์ด์œ 

  • JSX: JS๋ฅผ ํ™•์žฅํ•œ ๋ฌธ๋ฒ•์œผ๋กœ, JS ํŒŒ์ผ ์•ˆ์— HTML๊ณผ ์œ ์‚ฌํ•œ ๋งˆํฌ์—…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

  • ๊ธฐ์กด์˜ ์›น์€ ๋กœ์ง์€ JS์—, ๋งˆํฌ์—…์€ HTML ํŒŒ์ผ์— ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์—ˆ๋‹ค.
    ์›น์—์„œ ๋”์šฑ ๋†’์€ ์ˆ˜์ค€์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ํ—ˆ์šฉ๋˜๋ฉด์„œ, ๋กœ์ง์ด ์ปจํ…์ธ ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฐ ๋”์šฑ ์ค‘์š”ํ•˜๊ฒŒ ์ž‘์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
    ๋”ฐ๋ผ์„œ JS๊ฐ€ HTML์„ ์ œ์–ดํ•˜๊ฒŒ ๋˜์–ด ๋ Œ๋”๋ง ๋กœ์ง๊ณผ ๋งˆํฌ์—…์ด ํ•จ๊ป˜ ์กด์žฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.


3-2. JSX์˜ ๊ทœ์น™

1) ๋‹จ์ผ ๋ฃจํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ์—ฌ๋Ÿฌ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด, ํ•˜๋‚˜์˜ ๋ถ€๋ชจ ํƒœ๊ทธ๋กœ ๊ฐ์‹ผ๋‹ค.
  • <div></div> ํ˜น์€ <></>์„ ์‚ฌ์šฉํ•œ๋‹ค.
    ์ด๋Ÿฌํ•œ ๋นˆ ํƒœ๊ทธ๋ฅผ Fragment๋ผ๊ณ  ํ•˜๋ฉฐ, ๋ธŒ๋ผ์šฐ์ €์ƒ์˜ HTML ํŠธ๋ฆฌ ๊ตฌ์กฐ์—์„œ ํ”์ ์„ ๋‚จ๊ธฐ์ง€ ์•Š๊ณ  ๊ทธ๋ฃนํ™”ํ•ด์ค€๋‹ค.

๐Ÿง Why?

  • JSX๋Š” HTML์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ JS ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜๋œ๋‹ค.
  • ํ•จ์ˆ˜์—์„œ ๋‘ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— Fragment๋กœ ๋ฌถ์–ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

2) ๋ชจ๋“  ํƒœ๊ทธ๋ฅผ ๋‹ซ๋Š”๋‹ค.

  • ๋ช…์‹œ์ ์œผ๋กœ ํƒœ๊ทธ๋ฅผ ๋‹ซ์•„์•ผ ํ•œ๋‹ค.
  • <img>์ฒ˜๋Ÿผ ์ž์ฒด์ ์œผ๋กœ ๋‹ซ๋Š” ํƒœ๊ทธ๋„ ๋‹ซ์•„์ค˜์•ผ ํ•œ๋‹ค.

3) ๋Œ€๋ถ€๋ถ„์ด camelCase์ด๋‹ค.

  • JS์˜ ๋ณ€์ˆ˜๋ช… ๊ทœ์น™ ๋•Œ๋ฌธ์— HTML์˜ ์ผ๋ถ€ ์†์„ฑ์€ camelCase ํ‘œ๊ธฐ๋ฒ•์œผ๋กœ ๋ฐ”๋€Œ์–ด์•ผ ํ•œ๋‹ค!
  • JSX๋Š” JS๋กœ ๋ณ€ํ™˜๋˜๊ณ  JSX์— ์ž‘์„ฑ๋œ ์†์„ฑ๋“ค์€ JS ๊ฐ์ฒด์˜ key๊ฐ€ ๋œ๋‹ค.
    ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์†์„ฑ๋“ค์„ ๋ณ€์ˆ˜๋กœ ์ฝ์–ด๋“ค์ด๋Š”๋ฐ, JS์—๋Š” ๋ณ€์ˆ˜ ์ด๋ฆ„์— ๋Œ€ํ•œ ์ œํ•œ์ด ์žˆ๋‹ค. (์ด๋ฆ„์— ๋Œ€์‹œ๊ฐ€ ํฌํ•จ๋  ์ˆ˜ ์—†๊ณ , class ๊ฐ™์€ ์˜ˆ์•ฝ์–ด ๋ถˆ๊ฐ€๋Šฅ)
  • aria-*, data-*์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ์€ ์—ญ์‚ฌ์ ์ธ ์ด์œ ๋กœ ๋Œ€์‹œ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

3-3. string ์ „๋‹ฌ

  • ๋ฌธ์ž์—ด ์†์„ฑ์„ ์ „๋‹ฌํ•˜๋ ค๋ฉด ์ž‘์€๋”ฐ์˜ดํ‘œ or ํฐ๋”ฐ์˜ดํ‘œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}
  • ๋™์ ์œผ๋กœ ๊ฐ’์„ ์ „๋‹ฌํ•˜๋ ค๋ฉด ๋”ฐ์˜ดํ‘œ๋ฅผ {}๋กœ ๋ฐ”๊ฟ”์„œ JS๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}

3-4. ์ค‘๊ด„ํ˜ธ ์‚ฌ์šฉ

  • ์ค‘๊ด„ํ˜ธ {} ์•ˆ์—์„œ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํฌํ•จํ•œ ๋ชจ๋“  JS ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}

3-5. ๊ฐ์ฒด ์ „๋‹ฌ : ์ด์ค‘ ์ค‘๊ด„ํ˜ธ ์‚ฌ์šฉ

  • ์ด์ค‘ ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด CSS ๋“ฑ์˜ ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.
export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}

4. props

4-1. props๋ž€?

  • JSX ํƒœ๊ทธ์— ์ „๋‹ฌํ•˜๋Š” ์ •๋ณด์ด๋‹ค.
  • ์•„๋ž˜์˜ className, src, alt ๋“ฑ์ด ๋ชจ๋‘ props
  • ์ปดํฌ๋„ŒํŠธ์˜ ์œ ์ผํ•œ ์ธ์ž์ด๋‹ค.
    ์ปดํฌ๋„ŒํŠธ ํ•จ์ˆ˜๋Š” ํ•˜๋‚˜์˜ ์ธ์ž์ธ props ๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š”๋‹ค.
function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}

4-2. ์ปดํฌ๋„ŒํŠธ์— props ์ „๋‹ฌ

1) ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— props ์ „๋‹ฌ

export default function Profile() {
  return (
    <Avatar
      person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
      size={100}
    />
  );
}

2) ์ž์‹ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ props ์ฝ๊ธฐ

  • function ์ปดํฌ๋„ŒํŠธ์ด๋ฆ„ ๋’ค์— ์žˆ๋Š” ({}) ์•ˆ์—์„œ ๋‚˜์—ดํ•ด์„œ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ณดํ†ต ์ „์ฒด props ์ž์ฒด๋ฅผ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ณ„ props๋กœ ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์„ ์‚ฌ์šฉํ•œ๋‹ค.
function Avatar({ person, size }) {
  // person and size are available here
}

4-3. props ๊ธฐ๋ณธ๊ฐ’ ์ง€์ •

  • props๊ฐ€ ์ง€์ •๋˜์ง€ ์•Š์•˜์„ ๋•Œ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•˜๋ ค๋ฉด, ๋ณ€์ˆ˜ ๋’ค์— =๊ณผ ํ•จ๊ป˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค.
  • props๊ฐ€ ์ „๋‹ฌ๋˜์ง€ ์•Š๊ฑฐ๋‚˜ undefined๋กœ ์ „๋‹ฌ๋  ๋•Œ ๊ธฐ๋ณธ๊ฐ’์ด ์‚ฌ์šฉ๋œ๋‹ค.
  • null ๋˜๋Š” 0์œผ๋กœ ์ „๋‹ฌ๋˜๋Š” ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์ด ์•„๋‹Œ ์ „๋‹ฌ๋œ ๊ฐ’์ด ์‚ฌ์šฉ๋œ๋‹ค.

4-4. spread ๊ตฌ๋ฌธ์œผ๋กœ props ์ „๋‹ฌ

  • props ์ „์ฒด๋ฅผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌํ•˜๋ ค๋ฉด spread ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
function Profile(props) {
  return (
    <div className="card">
      <Avatar {...props} />
    </div>
  );
}

4-5. ์ž์‹์„ JSX๋กœ ์ „๋‹ฌํ•˜๊ธฐ

์•„๋ž˜์ฒ˜๋Ÿผ ์ปดํฌ๋„ŒํŠธ๋“ค๋ผ๋ฆฌ ์ค‘์ฒฉ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž

<Card>
  <Avatar />
</Card>
  • JSX ํƒœ๊ทธ ์•ˆ์— ๋‚ด์šฉ์„ ๋„ฃ์œผ๋ฉด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋Š” ์ด ๋‚ด์šฉ์„ children์ด๋ผ๋Š” prop์œผ๋กœ ๋ฐ›๊ฒŒ ๋œ๋‹ค.
import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

4-6. props๋Š” ์ฝ๊ธฐ ์ „์šฉ!

  • props๋ฅผ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ๋ง ๊ฒƒ!
  • props๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค๋ฅธ props (์ƒˆ๋กœ์šด ๊ฐ์ฒด)๋ฅผ ์ „๋‹ฌํ•˜๋„๋ก ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค.

5. ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง

5-1. null

  • ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜๊ณ  ์‹ถ์ง€ ์•Š์„ ๋•Œ๋Š” return null;

5-2. ์‚ผํ•ญ ์—ฐ์‚ฐ์ž

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

5-3. ๋…ผ๋ฆฌ && ์—ฐ์‚ฐ์ž

  • ์ฐธ์ผ ๋•Œ๋งŒ ๋ Œ๋”๋ง
  • ์กฐ๊ฑด์ด false์ด๋ฉด SX ํŠธ๋ฆฌ์ƒ์˜ ๊ตฌ๋ฉ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ , ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š”๋‹ค.
return (
  <li className="item">
    {name} {isPacked && 'โœ”'}
  </li>
);

6. ๋ชฉ๋ก ๋ Œ๋”๋ง

6-1. ๋ชฉ๋ก ๋ Œ๋”๋ง

const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario Josรฉ Molina-Pasquel Henrรญquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

export default function List() {
  const listItems = people.map(person =>
    <li>{person}</li>
  );
  return <ul>{listItems}</ul>;
}

6-2. key

  • ๊ฐ ๋ชฉ๋ก์˜ JSX ์š”์†Œ์—๋Š” ๊ฐ ์š”์†Œ ๊ฐ„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ž์—ด ๋˜๋Š” ์ˆซ์ž key๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ถ€์—ฌํ•ด์•ผ ํ•œ๋‹ค.
  • key๋Š” ํ˜•์ œ๊ฐ„ ๊ณ ์œ ํ•ด์•ผ ํ•˜๋ฉฐ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
  • key๋ฅผ ๋žœ๋ค์œผ๋กœ ์ƒ์„ฑํ•˜๋ฉด (key={Math.random()} โŒ) ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ๋งค๋ฒˆ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์™€ DOM์ด ๋‹ค์‹œ ์ƒ์„ฑ๋˜์–ด ์†๋„๊ฐ€ ๋Š๋ ค์ง€๊ณ  ํ•ญ๋ชฉ ๋‚ด๋ถ€์˜ ์‚ฌ์šฉ์ž ์ž…๋ ฅ๋„ ์†์‹ค๋˜๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ์— ๊ธฐ๋ฐ˜ํ•œ ์•ˆ์ •์ ์ธ ID๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ID / crypto.randomUUID() / uuid ํŒจํ‚ค์ง€ โญ•๏ธ)
  • key๋Š” prop์œผ๋กœ ๋ฐ›์ง€ ์•Š์œผ๋ฏ€๋กœ ID๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ณ„๋„์˜ ํ”„๋กœํผํ‹ฐ๋กœ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค.

key์˜ ์—ญํ• 

  • ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์–ด๋–ค ๋ฐฐ์—ด ํ•ญ๋ชฉ์— ํ•ด๋‹นํ•˜๋Š”์ง€ key๋ฅผ ํ†ตํ•ด ์‹๋ณ„ํ•˜๋ฉฐ
    ์œ„์น˜๋‚˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ React๊ฐ€ ๊ฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

7. ์ปดํฌ๋„ŒํŠธ ์ˆœ์ˆ˜์„ฑ ์œ ์ง€

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

7-1. ์ˆœ์ˆ˜์„ฑ Purity : ์ˆ˜์‹์œผ๋กœ์„œ์˜ ์ปดํฌ๋„ŒํŠธ

1) ์ˆœ์ˆ˜ ํ•จ์ˆ˜์˜ ํŠน์ง•

์ˆœ์ˆ˜ ํ•จ์ˆ˜๋Š” ์•„๋ž˜์˜ ํŠน์ง•์„ ๊ฐ€์ง„ ํ•จ์ˆ˜์ด๋‹ค.

side effects๊ฐ€ ์—†๋‹ค.

  • ํ˜ธ์ถœ๋˜๊ธฐ ์ „์— ์กด์žฌํ–ˆ๋˜ ๊ฐ์ฒด๋‚˜ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•จ์ˆ˜๊ฐ€ ์™ธ๋ถ€ ์„ธ๊ณ„์™€ ๋…๋ฆฝ์ ์ด๋ฉฐ, ์™ธ๋ถ€ ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

์ฐธ์กฐ ํˆฌ๋ช…์„ฑ

  • ๋™์ผํ•œ ์ž…๋ ฅ์ด ์ฃผ์–ด์ง€๋ฉด ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ํ•จ์ˆ˜์˜ ๋™์ž‘์ด ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๋ฉฐ ์ผ๊ด€์„ฑ ์žˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค.

React๋Š” ์ด ๊ฐœ๋…์„ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„๋˜์–ด ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ˆœ์ˆ˜ ํ•จ์ˆ˜๋ผ๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.
์ฆ‰, React ์ปดํฌ๋„ŒํŠธ๋Š” ๋™์ผํ•œ ์ž…๋ ฅ์ด ์ฃผ์–ด์กŒ์„ ๋•Œ ํ•ญ์ƒ ๋™์ผํ•œ JSX๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

2) Side Effects

  • ์•„๋ž˜๋Š” Side Effects๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™์„ ์–ด๊ธฐ๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.
  • ์™ธ๋ถ€์—์„œ ์„ ์–ธ๋œ guest ๋ณ€์ˆ˜๋ฅผ ์ฝ๊ณ  ์“ฐ๊ณ  ์žˆ์–ด ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค๋ฅธ JSX๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค.
let guest = 0;

function Cup() {
  // โŒ Bad: ๊ธฐ์กด ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

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

  • 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} />
    </>
  );
}

  • ๋ Œ๋”๋ง์€ ์–ธ์ œ๋“ ์ง€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠน์ •ํ•œ ์ˆœ์„œ๋Œ€๋กœ ๋ Œ๋”๋ง๋  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค.
    ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์ด ์„œ๋กœ ์˜์กดํ•˜๊ฑฐ๋‚˜ ์กฐ์ •ํ•˜์ง€ ์•Š๊ณ  ๋…๋ฆฝ์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.

7-2. StrictMode

  • ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง์— ์‚ฌ์šฉํ•˜๋Š” ์„ธ ์ข…๋ฅ˜์˜ ์ž…๋ ฅ๊ฐ’์ด ์žˆ๋‹ค. props, state, context
    ์ด ์ž…๋ ฅ๋“ค์„ ํ•ญ์ƒ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์ทจ๊ธ‰ํ•ด์•ผ ํ•œ๋‹ค.
    ์‚ฌ์šฉ์ž ์ž…๋ ฅ์— ๋Œ€ํ•œ ๋ฐ˜์‘์œผ๋กœ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ณ€์ดํ•˜๋Š” ๋Œ€์‹  setState๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • React๊ฐ€ ์ œ๊ณตํ•˜๋Š” StrictMode์—์„œ๋Š” ๊ฐ ์ปดํฌ๋„ŒํŠธ์˜ ํ•จ์ˆ˜๋ฅผ ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•ด์„œ ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์–ด๊ธฐ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ๋Š” ๋ฐ ๋„์›€์ด ๋œ๋‹ค.
  • StrictMode๋ฅผ ์„ ํƒํ•˜๋ ค๋ฉด ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ <React.StrictMode>๋กœ ๊ฐ์‹ธ๋ฉด ๋œ๋‹ค.

7-3. Side Effects๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•

  • React์—์„œ Side effects๋Š” ๋ณดํ†ต ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์— ์†ํ•œ๋‹ค.
  • ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ์ •์˜๋˜์–ด ์žˆ์ง€๋งŒ ๋ Œ๋”๋ง ์ค‘์— ์‹คํ–‰๋˜์ง€๋Š” ์•Š๋Š”๋‹ค.
    ๋”ฐ๋ผ์„œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋Š” ์ˆœ์ˆ˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • Side effects์— ์ ํ•ฉํ•œ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋ฉด, useEffect๋ฅผ ํ˜ธ์ถœํ•ด Side effects๋ฅผ ์ฒจ๋ถ€ํ•  ์ˆ˜ ์žˆ๋‹ค.
    ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ Œ๋”๋ง ํ›„ Side effects๊ฐ€ ํ—ˆ์šฉ๋  ๋•Œ ์‹คํ–‰ํ•˜๋„๋ก ์ง€์‹œํ•œ๋‹ค.
    ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ์ตœํ›„์˜ ์ˆ˜๋‹จ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. (์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ)

7-4. React๊ฐ€ ์ˆœ์ˆ˜์„ฑ์„ ์ค‘์š”์‹œํ•˜๋Š” ์ด์œ 

1) ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋‹ค๋ฅธ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. (ex ์„œ๋ฒ„)

  • ๋™์ผํ•œ ์ž…๋ ฅ์— ๋Œ€ํ•ด ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์€ ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

2) memo๋ฅผ ํ†ตํ•ด ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

  • ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ์บ์‹ฑํ•ด๋„ ์•ˆ์ „ํ•˜๋‹ค.

3) ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ์‹œ ๋ Œ๋”๋ง ํ”„๋กœ์„ธ์Šค๋ฅผ ์žฌ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ Œ๋”๋ง ์ค‘ ๊นŠ์€ ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์—์„œ ์–ด๋–ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ์˜ค๋ž˜๋œ ๋ Œ๋”๋ง์„ ์™„๋ฃŒํ•˜๋Š” ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ•˜์ง€ ์•Š๊ณ  ๋ Œ๋”๋ง์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ˆœ์ˆ˜์„ฑ ๋•๋ถ„์— ์–ด๋Š ์‹œ์ ์—์„œ๋“  ๋ Œ๋”๋ง์„ ์•ˆ์ „ํ•˜๊ฒŒ ์ค‘๋‹จํ•˜๊ณ  ์žฌ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ!
728x90
๋ฐ˜์‘ํ˜•

'React' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[React] Class Component  (0) 2023.10.02
[React] Quick Start :: 80% of React concepts  (0) 2023.09.12
[React-Native] React-Navigation :: ํ™”๋ฉด ์ „ํ™˜ํ•˜๊ธฐ  (0) 2022.11.03