공부기록/[강의노트] Udemy React 완벽가이드 1~100

# 37 [udemy React 완벽 가이드 노트] 컴포지션 (Composition) 컴포넌트 합치기

Jenner 2022. 9. 8. 16:13

 

 

 

Expenses.js 파일


import "./Expenses.css";
import ExpenseItem from "./ExpenseItem";

function Expenses(props) {
  return (
    <div className="expenses">
      <ExpenseItem
        title={props.expenses[0].title}
        amount={props.expenses[0].amount}
        date={props.expenses[0].date}
      />
      <ExpenseItem
        title={props.expenses[1].title}
        amount={props.expenses[1].amount}
        date={props.expenses[1].date}
      />
      <ExpenseItem
        title={props.expenses[2].title}
        amount={props.expenses[2].amount}
        date={props.expenses[2].date}
      />
      <ExpenseItem
        title={props.expenses[3].title}
        amount={props.expenses[3].amount}
        date={props.expenses[3].date}
      />
    </div>
  );
}

export default Expenses;

Expenses파일은 여러개의 ExpenseItem 컴포넌트를 렌더링하고 있는 파일이다. 

(ExpenseItem은 각각의 title과 amount, date를 렌더링해주는 컴포넌트다)

 

그런데 여기에서 border-radius나 box-shadow같은 속성은 중복된다.

이 중복을 없애기 위해 컴포지션을 사용할 수 있다. 

 

먼저 Card.js를 만들고 Card.css를 임포트해준다. 

Card.css에는 중복되는 속성을 넣어준다. 

 

 

Card.css


.card {
  border-radius: 12px;
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.25);
}

 

 

Card.js


import "./Card.css";

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

export default Card;

 

 

 

 

Card.js 파일에서 div태그 안에 props.children을 넣은 이유


 

<div>{props.children}</div>

 

    <Card className="expenses">
     <ExpenseItem />
     <ExpenseItem />
     <ExpenseItem />
    </Card>

이렇게 다른 컴포넌트를 Card 컴포넌트가 감싸고 있는 모습이 될 때는 

안의 자식요소가 보이지 않을 수 있다.

그럴 때 prop.children을 추가함으로써 자식요소를 함께 렌더링할 수 있게 된다. 

 

 

 

Expenses.js 파일에서 Card 컴포넌트 사용해보기


 

그리고 이 Card 컴포넌트를 

Expenses.js 파일에서 ExpenseItem들 전체를 감싸고 있는 div와 교체해준다. 이때 import해주는 것도 잊지 말자.

 

import "./Expenses.css";
import ExpenseItem from "./ExpenseItem";
import Card from "./Card";

function Expenses(props) {
  return (
    <Card className="expenses">
      <ExpenseItem
        title={props.expenses[0].title}
        amount={props.expenses[0].amount}
        date={props.expenses[0].date}
      />
      <ExpenseItem
        title={props.expenses[1].title}
        amount={props.expenses[1].amount}
        date={props.expenses[1].date}
      />
      <ExpenseItem
        title={props.expenses[2].title}
        amount={props.expenses[2].amount}
        date={props.expenses[2].date}
      />
      <ExpenseItem
        title={props.expenses[3].title}
        amount={props.expenses[3].amount}
        date={props.expenses[3].date}
      />
    </Card>
  );
}

export default Expenses;

 

이 때 className="expenses" 의 속성이 적용되지 않는 것을 알 수 있다. 

적용을 시키기 위해서 Card.js 파일을 약간 수정해준다. 

 

 

파일마다 달리 적용되는 Card의 className속성 적용하기


import "./Card.css";

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

export default Card;

 

중복되는 스타일이 적용되는 다른 컴포넌트들에도 

컴포지션을 활용하여 중복을 제거해 줄 수 있게 된다.