본문 바로가기
JS/React 강의

[React] 3. props / props.children 컴포지션

by GiraffePark 2023. 2. 7.

안녕하세요. 박기린 입니다.

이번에는 React 컴포넌트의 핵심 중 하나인 props에 대해 알아보겠습니다.

 

 

 

props의 역할

React 컴포넌트는 다른 컴포넌트(파일)의 데이터를 바로 가져올 수 없습니다. 그래서 HTML의 태그가 attribute를 이용해서 데이터를 주고받는 것처럼, React 컴포넌트도 props라는 것을 이용해서 데이터를 주고받습니다.

 

 

 

 

 


props를 전달하는 방법

// App.js
function App() {
  const expenses = [
    {
      id: "e1",
      title: "Car Insurance",
      amoount: 294.67,
      date: new Date(2022, 2, 20),
    },
  ];
  return (
    <div>
      {/* 소문자로 시작 - html */}
      <h2>Let's get started!</h2>

      {/* 대문자로 시작 - 컴포넌트 */}
      <ExpenseItem title={expenses[0].title} amount ={expenses[0].amoount} date={expenses[0].date}></ExpenseItem>
    </div>
  );
}

이 코드 중에서,

 

 

<ExpenseItem title={expenses[0].title} amount ={expenses[0].amoount} date={expenses[0].date}></ExpenseItem>

ExpenseItem이라는 컴포넌트를 보면,

1. title, amount, date 라는 이름 옆에 '={}'가 붙어 있고
2. 중괄호 안에는 변수가 담겨 있습니다.

ExpenseItem에 title, amount, date 라는 이름으로 props를 전달하고, 각각 어떤 데이터를 담을지는  ' ={} ' 의 중괄호 안에 지정해주는 방식입니다.

 

 

 

 

 

 


props를 전달받는 방법

그렇다면 전달한 props를 해당 컴포넌트(ExpenseItem)에서는 어떻게 받을 수 있을까요?

 

// ExpenseItem.js
function ExpenseItem(props) {
  return (
    <div className = 'expense-item'> 
      <div className='expense-item__description'>{props.date.toISOString()}</div>
      <div className='expense-item__price'>
        <h2>{props.title}</h2> 
        <div>${props.amount}</div>
      </div>
    </div>
  );
}

React는 props를 주고받을 때, 단 하나의 매개변수 만을 사용합니다. 이를 관용상으로 props라고 짓습니다.

컴포넌트 함수의 매개변수로 props를 지정해주면, {key: value} 형태로 된 데이터를 받을 수 있습니다.

1. App.js가 ExpenseItem.js로 title = 'hello' 라는 값을 보내면
2. ExpenseItem.js에서 {title: 'hello'} 형태로 된 데이터가 props.title에 담아집니다.

 

 

 

 

 

 


Composition - props.children

Composition은 '합성'을 뜻하고, React에서는 컴포넌트 간의 합성을 뜻합니다.

 

//ExpenseItem.js - 위의 ExpenseItem과는 다른 버전.
function ExpenseItem(props) {
  return (
    <Card className="expense-item">
      <ExpenseDate date = {props.date}/>
      <div className="expense-item__description">
        <h2>{props.title}</h2>
        <div className="expense-item__price">
          <div>${props.amount}</div>
        </div>
      </div>
    </Card>
  );
}

위의 코드를 보면 ExpenseItem 안에 ExpenseDate라는 컴포넌트가 있습니다. 그리고 그 위에 Card라는 컴포넌트가 있습니다.

 

 

 

<Card>
	<ExpenseDate />
</Card>

이러한 형태로 구성되어 있습니다. Card, ExpenseDate는 직접 만든 커스텀 컴포넌트입니다.

커스텀 컴포넌트 안에 컴포넌트를 래핑하는 방식으로 컴포넌트 간의 합성(컴포지션)이 일어납니다.

원래 자바스크립트는 클래스 간의 상속(inheritance)를 통해서 작동하지만, 리액트는 상속이 아니라 합성을 대부분 이용합니다.

 

 

 

 

그러면 어떻게 이런 형태로 컴포넌트 안에 컴포넌트를 합성(컴포지션)할 수 있을까요?

// Card.js
function Card(props) {
  const classes = 'card ' + props.className
  return <div className={classes}>{props.children}</div>;
}

 

바로 props.children을 이용하는 것입니다. 

이때 children은 React에서 예약어로 설정되어 있어, 꼭! 이름을 {props.children}으로 설정한 후 JSX 코드에 넣어주어야 합니다.

 

 

+) 팁 - 커스텀 컴포넌트에서도 className props 사용하기 :  위의 Card 컴포넌트 처럼, className에 들어갈 String을 따로 변수/상수로 빼준 후, props.className을 연결해주면, 커스텀 컴포넌트에서도 className props를 설정할 수 있습니다.

반응형