아래와 같이 하드코딩하여 아이템 리스트를 렌더링 하면 아이템의 변화가 있을때 동적으로 변하지 않는다. 그렇다면 어떻게 동적으로 아이템들을 렌더링 할 수 있을까?
const Expense = ({expenses}) =>{
return (
<>
<ExpenseItem
title={expenses.title}
amount={expenses.amount}
date={expenses.date}
/>
<ExpenseItem
title={expenses.title}
amount={expenses.amount}
date={expenses.date}
/>
</>
)
}
아래 코드와 같이 JSX에서 map메서드를 사용하여 코드를 작성하면 expenses의 값이 변경 되더라도 동적으로 렌더링 할 수 있다.!!😆
const Expense = ({expenses}) =>{
return (
<>
{expenses.map((expense)=>(
<ExpenseItem
title={expense.title}
amount={expense.amount}
date={expense.date}
/>
)}
</>
)
}
하지만 위에서 처럼 코드를 작성하면 동작은 잘 되지만 한가지 경고를 받는다.😨😨
이때 Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. key는 엘리먼트에 안정적인 고유성을 부여하기 위해 배열 내부의 엘리먼트에 지정해줘야 한다.
const Expense = ({expenses}) =>{
return (
<>
{expenses.map((expense)=>(
<ExpenseItem
title={expense.title}
amount={expense.amount}
date={expense.date}
key={expense.id}
/>
)}
</>
)
}
key를 선택할때는 항목의 인덱스를 key로 사용하는 것 보다 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는것이 좋다.
만약 항목의 순서가 매번 바뀔수 있는 경우에 항목의 인덱스를 key로 사용해버리면 성능이 저하되거나 컴포넌트의 state와 관련된 문제가 발생할 수있다.
만약 아이템 리스트의 길이가 0일때 또는 0이상일때 렌더릴을 다르게 하고 싶다면 간단하게 삼항 연산자 또는 &&, 따로 변수를 지정해서 사용할 수 있다.
{filteredExpenses.length === 0 ? (<p>지출 내역 없음.</p>) : (
filteredExpenses.map((expense) => (
<ExpenseItem
title={expense.title}
amount={expense.amount}
date={expense.date}
key={expense.id}
/>
))
)}
&& 연산자의 경우 앞의 조건이 참이면 실행된다.
{filteredExpenses.length === 0 && <p>지출 내역 없음.</p>}
{filteredExpenses.length > 0 && filteredExpenses.map((expense) => (
<ExpenseItem
title={expense.title}
amount={expense.amount}
date={expense.date}
key={expense.id}
/>
))}
이 경우가 가장 깔끔하다
const Expense = (expens) => {
let expensesContent = <p>지출 내역 없음.</p>;
if (filteredExpenses.length > 0) {
expensesContent = filteredExpenses.map((expense) => (
<ExpenseItem
title={expense.title}
amount={expense.amount}
date={expense.date}
key={expense.id}
/>
));
}
return (
<>
{expensesContent}
</>
)
}