컴포넌트 트리에서 봤다시피 컴포넌트 안에는 작은 컴포넌트들로 구성되어 있습니다. 그렇다면 상위 컴포넌트 안에 있는 변수는 스코프 범위가 더 넓으므로 하위 컴포넌트에서도 접근할수 있습니다. 하지만 컴포넌트의 파일이 나뉘어 다른 파일에서 import
해왔을 경우에는 다릅니다.
상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할수 가 없습니다. 따라서 이경우에 Props
라는 개념을 사용합니다. 컴포넌트에 속성을 추가하여 해당 속성에 템플릿 레터럴을 사용하여 값
을 넘겨주는 것입니다.
Props는 하위 컴포넌트에서 상위 컴포넌트에 넘겨 받은 값을 객체형태로 반환한 값입니다. 따라서 하위 컴포넌트에서 상위 컴포넌트에 전달받은 값을 접근할 때에 props.attribute
형태로 접근합니다.
물론 props 라는 것은 JS 문법으로 이름 자체에 의미가 있는 키워드는 아닙니다.
App.js
import ExpenseItem from "./components/ExpenseItem";
function App() {
const expense = [
{
id: "e1",
title: "New Desk (Wooden)",
amount: 450,
date: new Date(2021, 7, 7),
},
{
id: "e2",
title: "New Desk (Wooden)",
amount: 450,
date: new Date(2021, 7, 7),
},
{
id: "e3",
title: "New Desk (Wooden)",
amount: 450,
date: new Date(2021, 7, 7),
},
{
id: "e4",
title: "New Desk (Wooden)",
amount: 450,
date: new Date(2021, 7, 7),
},
];
return (
<div>
<h2>Let's get started!</h2>
{expense.map((item) => {
return (
<ExpenseItem
title={item.title}
id={item.id}
amount={item.amount}
date={item.date}
/>
);
})}
</div>
);
}
export default App;
ExpenseItem.js
import "./ExpenseItem.css";
export default function ExpenseItem(props) {
return (
<div className="expense-item">
<div>{props.date.toISOString().slice(0, 10)}</div>
<div className="expense-item__description">
<h2>{props.title}</h2>
<div className="expense-item__price">${props.amount}</div>
</div>
</div>
);
}
상위 컴포넌트인 App.js
에서 속성을 넘겨주면 하위 컴포넌트인 ExpenseItem.js
에서 props 라는 객체로 속성을 한번에 넘겨 받아서 컴포넌트를 동적으로 구성하는 모습입니다.
❗️ Props를 사용하는 함수 컴포넌트는
순수 함수
처럼 사용해야 합니다. 순수함수란 입력받은 인수를 변형하지 않고 값을 반환하는 함수 입니다.map
메서드는 순수함수라고 할수 있습니다. 즉, props로 전달하는 값은 컴포넌트안에서 가공될순 있으나 전달과정에서 props로 전달되는 원본 변수가 변형되어서는 안됩니다.props는 읽기 전용입니다.