๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Frontend Dev/React

React ๊ธฐ๋ณธ, props ์‚ฌ์šฉํ•˜๊ธฐ

๋ฐ˜์‘ํ˜•

๐Ÿ‘พ props๋ž€?

 • props๋Š” ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์„ ์˜๋ฏธํ•œ๋‹ค. props๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š” immutableํ•œ ๋ฐ์ดํ„ฐ์ด๋‹ค.

 • props๋Š” ๋ถ€๋ชจ ์ปจํฌ๋„ŒํŠธ์—์„œ ์ž์‹ ์ปจํฌ๋„ŒํŠธ๋กœ ๋˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ ์ž์ฒด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์ฆ‰, ์–ด๋–ค ๊ฐ’์„ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ์ „๋‹ฌํ•ด์ค˜์•ผ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 • React ์ปดํฌ๋„ŒํŠธ๋Š” JavaScript ํ•จ์ˆ˜์™€ ํด๋ž˜์Šค๋กœ, props๋ฅผ ํ•จ์ˆ˜์˜ ์ „๋‹ฌ์ธ์ž(arguments)์ฒ˜๋Ÿผ ์ „๋‹ฌ๋ฐ›์•„ ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ™”๋ฉด์— ์–ด๋–ป๊ฒŒ ํ‘œ์‹œ๋˜๋Š”์ง€๋ฅผ ๊ธฐ์ˆ ํ•˜๋Š” React ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ดˆ ๋ Œ๋”๋ง ๋  ๋•Œ ํ™”๋ฉด์— ์ถœ๋ ฅํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์€ ์ดˆ๊นƒ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 • props๋กœ ์–ด๋–ค ํƒ€์ž…์˜ ๊ฐ’๋„ ๋„ฃ์–ด ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก props๋Š” ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค.

 • props๋Š” ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์•„ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๊ฐ’์œผ๋กœ ์ฝ๊ธฐ ์ „์šฉ(read-only)์ด๋‹ค.

์ฝ๊ธฐ ์ „์šฉ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด props๋ฅผ ์ „๋‹ฌ๋ฐ›์€ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ props๋ฅผ ์ง์ ‘ ์ˆ˜์ • ์‹œ props๋ฅผ ์ „๋‹ฌํ•œ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฐ’์— ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์˜๋„ํ•˜์ง€ ์•Š์€ side effect๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋˜๊ณ  ์ด๋Š” React์˜ ๋‹จ๋ฐฉํ–ฅ, ํ•˜ํ–ฅ์‹ ๋ฐ์ดํ„ฐ ํ๋ฆ„ ์›์น™(React is all about one-way data flow down the component hierarchy)์— ์œ„๋ฐฐ๋œ๋‹ค.

์ฆ‰, ๋ชจ๋“  React ์ปดํฌ๋„ŒํŠธ๋Š” ์ž์‹ ์˜ props๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ๋ฐ˜๋“œ์‹œ ์ˆœ์ˆ˜ ํ•จ์ˆ˜(์ž…๋ ฅ๊ฐ’์„ ๋ฐ”๊พธ๋ ค ํ•˜์ง€ ์•Š๊ณ  ํ•ญ์ƒ ๋™์ผํ•œ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•ด ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜)์ฒ˜๋Ÿผ ๋™์ž‘ํ•ด์•ผ ํ•œ๋‹ค.

 

 

๐Ÿ‘พ props ์‚ฌ์šฉํ•˜๋Š”๋ฒ• (๊ธฐ๋ณธ)

 props๋ฅผ ์‚ฌ์šฉํ•ด ์ „์ฒด ์†์„ฑ์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜๋„ ์žˆ๊ณ , {์ค‘๊ด„ํ˜ธ ๋‚ด๋ถ€์— ์†์„ฑ ์ด๋ฆ„์„ ์ง€์ •ํ•ด} ์›ํ•˜๋Š” ์†์„ฑ๊ฐ’๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

 1. props๋กœ ์ „์ฒด ์†์„ฑ ๊ฐ€์ ธ์˜ค๊ธฐ

// Parent ์ปดํฌ๋„ŒํŠธ (์‹ค์ œ ํ™”๋ฉด์— render๋˜๋Š” ์ƒ์œ„ component)
function Parent() {
  return (
    <Child title="WEB" sub="welcome to the world wide web" />
    // 1. ์†์„ฑ ์ง€์ •
  );
};

// Child ์ปดํฌ๋„ŒํŠธ
function Child(props) { // 2. props ๊ฐ€์ ธ์˜ค๊ธฐ

  console.log(props) 
  /* 
    props๋Š” ๊ฐ์ฒด์˜ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง„๋‹ค. 
    {title: 'WEB', sub: 'welcome to the world wide web'}
  */
  
  return (
    <div>
      <h1>{props.title}</h1>
      <p>{props.sub}</p>
    </div>
    // 3. {} ์•ˆ์— ์‚ฌ์šฉํ•˜๋ ค๋Š” ์†์„ฑ ์ž‘์„ฑ
  );
};

 

 2. ์›ํ•˜๋Š” ์†์„ฑ๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ• { … }

// Parent ์ปดํฌ๋„ŒํŠธ (์‹ค์ œ ํ™”๋ฉด์— render๋˜๋Š” ์ƒ์œ„ component)
function Parent() {
  return (
    <Child title="WEB" sub="welcome to the world wide web" />
    // 1. ์†์„ฑ ์ง€์ •
  );
};

// Child ์ปดํฌ๋„ŒํŠธ
function Child({ title, sub }) { // 2. ์›ํ•˜๋Š” ์†์„ฑ๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ• {}

  console.log(title, sub) 
  // WEB, welcome to the world wide web
  
  return (
    <div>
      <h1>{title}</h1>
      <p>{sub}</p>
    </div>
    // 3. {} ์•ˆ์— ์‚ฌ์šฉํ•˜๋ ค๋Š” ์†์„ฑ ์ž‘์„ฑ
  );
};

 

 

 

๐Ÿ‘พ props.children

 props.children์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—ฌ๋Š” ํƒœ๊ทธ์™€ ๋‹ซ๋Š” ํƒœ๊ทธ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋Š” ๊ฒฝ์šฐ ํƒœ๊ทธ์˜ value๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

 props.children๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํฌ๋„ŒํŠธ ์ž์ฒด๋ฅผ props๋กœ ์ „๋‹ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

 ๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป example 1

function Parent() {
  return (
    <Child title="sayHi">Hi, React!</Child> 
  );
};

function Child(props) {

  console.log(props) // {title: 'sayHi', children: 'Hi, React!'}

  return (
    <div>{props.children}</div> // Hi, React! ์ถœ๋ ฅ
  );
};

 ↑ ์œ„ ์ฝ”๋“œ๋Š” props๋กœ ์ „์ฒด ์†์„ฑ์„ ๊ฐ€์ ธ์˜ค๊ณ , ์•„๋ž˜ ์ฝ”๋“œ๋Š” {children}์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์˜ value๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

 ๊ฒฐ๊ณผ์ ์œผ๋กœ๋Š” ๋‘ ์ฝ”๋“œ๋Š” ๊ฐ™์€ ๋‚ด์šฉ์„ ๋ณด์—ฌ์ค€๋‹ค. (Hi, React! ์ถœ๋ ฅ) ↓

function Parent() {
  return (
    <Child title="sayHi">Hi, React!</Child> 
  );
};

function Child({ children }) {

  console.log(children) // Hi, React!

  return (
    <div>{children}</div> // Hi, React! ์ถœ๋ ฅ
  );
};

 

 ๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป example 2

function Parent() {
  const apple = "๐ŸŽ";
  const orange = "๐ŸŠ";

  return (
    <Child>{apple}{orange}</Child> 
  );
};

function Child(props) {
  console.log(props.children) // ['๐ŸŽ', '๐ŸŠ']
  return (
    <div>{props.children}</div> 
  );
};

 

 

๐Ÿ‘พ props๋กœ ๋™์ ์œผ๋กœ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑํ•˜๊ธฐ (key)

// App component (์‹ค์ œ ํ™”๋ฉด์— render๋˜๋Š” component)
function App() {
  const topics = [
    { id:1, title:'html', body: 'html is...' },
    { id:2, title:'css', body: 'css is...' },
    { id:3, title:'js', body: 'js is...' },
  ]

  return (
      <Nav topics={topics}></Nav>
  )
}

// Nav component
function Nav(props) {
  console.log(props) // props๋กœ App ์ปดํฌ๋„ŒํŠธ์˜ topics ๋ฐฐ์—ด์„ ๋ฐ›๋Š”๋‹ค. 

  /* for๋ฌธ ์‚ฌ์šฉ
  const list = []
  for(let i=0; i<props.topics.length; i++) {
    let j = props.topics[i];
    list.push( <li key={j.id}><a href={`/${j.id}`}>{j.title}</a></li> )
  }
  */

  // map์‚ฌ์šฉ
  const list = props.topics.map((value) => {
    return <li key={value.id}><a href={`/${value.id}`}>{value.title}</a></li>
  });

  return(
    <nav>
      <ol>
        {list}
      </ol>
    </nav>
  )
}

 

• list์™€ key

 list์— key๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์ŠคํŠธ ๊ฐ ํ•ญ๋ชฉ์— key๋ฅผ ๋„ฃ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒฝ๊ณ ๊ฐ€ ํ‘œ์‹œ๋œ๋‹ค. (Warning: Each child in a list should have a unique "key" prop.)

 

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

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

 

 Math.random() ๊ฐ™์€ ๊ฐ’์„ key๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค. React๊ฐ€ ํ•ญ๋ชฉ ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋˜๋Š” ๋‹ค์‹œ ์ •๋ ฌํ•  ์‹œ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก key๋Š” ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๊ณผ์ • ๋™์•ˆ “์•ˆ์ •์ ์œผ๋กœ ์‹๋ณ„ ๊ฐ€๋Šฅ”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ƒ์ ์œผ๋กœ, Key๋Š” id์™€ ๊ฐ™์ด ๋ฐ์ดํ„ฐ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์œ ์ผํ•˜๊ณ  ์•ˆ์ •์ ์ธ ์‹๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

 

 

๐Ÿ‘พ defaultProps

 ๊ฐ’์ด ์ง€์ •๋˜์ง€ ์•Š์•˜์„ ๋•Œ, props์— ๊ธฐ๋ณธ๊ฐ’์„ ์ฃผ๊ธธ ์›ํ•œ๋‹ค๋ฉด โ‘  ๋ณ€์ˆ˜ ๋ฐ”๋กœ ๋’ค์— =๊ณผ ํ•จ๊ป˜ ๊ธฐ๋ณธ๊ฐ’์„ ๋„ฃ์–ด ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น์„ ํ•ด์ฃผ๊ฑฐ๋‚˜, โ‘ก ์ปดํฌ๋„ŒํŠธ์— defaultProps ๊ฐ’์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 → ๊ธฐ๋ณธ๊ฐ’์€ ํ•ด๋‹น prop์ด ์—†๊ฑฐ๋‚˜ {undefined}๋กœ ์ „๋‹ฌ๋  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

 → {null} ๋˜๋Š” {0}์œผ๋กœ ์ „๋‹ฌ๋œ ๊ฒฝ์šฐ๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.

 

 1. ๋ณ€์ˆ˜ ๋ฐ”๋กœ ๋’ค์— = ๊ณผ ํ•จ๊ป˜ ๊ธฐ๋ณธ๊ฐ’ ๋„ฃ๊ธฐ

function App() {
  return (
    <User name="fay" /> // age prop์ด ์—†๋Š” User component
  )
}

function User({ name, age = 20 }) { // age ๊ธฐ๋ณธ๊ฐ’ ์ง€์ •
  
  console.log(name, age) // fay, 20

  return (
    <div>
      <p>name: {name}</p>
      <p>age: {age}</p>
    </div>
  )
}

 

 2. defaultProps ์ •์˜ 

function App() {
  return (
    <div>
      <List list={undefined} /> 
      {/* list๊ฐ€ undefined์ธ ๊ฒฝ์šฐ */}
    </div>
  )
}

const List = ({ list }) => {

  const items = list.map((items) => {
      return <li key={items.id}></li>
  });

  return (
    <div>
        <h2>๋ฆฌ์ŠคํŠธ</h2>
        <div>
            <p>{list.length}๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.</p>
            <ul>
                {items}
            </ul>
        </div>
    </div>
  )
}

// List์˜ defaultProps
List.defaultProps =  {
    list: [],
};

 

 

๐Ÿ‘พ Props Drilling๊ณผ ์ƒํƒœ๊ด€๋ฆฌ

 

React์˜ Props Drilling๊ณผ ์ƒํƒœ๊ด€๋ฆฌ

๐Ÿ‘พ Props Drilling์ด๋ž€? Props Drilling์€ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์˜ state๋ฅผ props๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•˜๊ณ ์ž ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ ์‚ฌ์ด๋Š” props๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์šฉ๋„๋กœ๋งŒ ์“ฐ์ด๋Š” ์ปดํฌ๋„ŒํŠธ๋“ค์„ ๊ฑฐ์น˜๋ฉด์„œ ๋ฐ์ดํ„ฐ๋ฅผ

fay-story.com

 

 


โœ๏ธ ๊ณต๋ถ€ํ•˜๋ฉฐ ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์ •๋ณด๋‚˜ ๋” ๊ณต์œ ํ•  ๋‚ด์šฉ์ด ์žˆ์œผ๋ฉด ๋Œ“๊ธ€๋กœ ์•Œ๋ ค์ฃผ์„ธ์š”!

์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜Š

๋ฐ˜์‘ํ˜•