똑같은 삽질은 2번 하지 말자
React vol.3 (key, 조건문의 다양한 활용, 동적 스타일) 본문
개요
React JS 를 공부하면서 기본을 정리해두고자 작성
(key, 조건문의 다양한 활용, 동적 스타일 )
1. 리액트의 key란?
이건 vue의 v-for의 key와 개념인데 어떤 리스트가 있고 그 리스트를 표현하고 있는 컴포넌트가 있다.
그 리스트는 반복적인 컴포넌트 명시 보다는 대부분 map이나 forEach를 이용해 코드를 작성할 것인데
만약에 리스트의 아이템 컴포넌트에 props key를 부여 안했다면 이하의 경고창을 볼 수 있다.
원인은 리스트에서 요소를 추가할 때 확실하게 알 수 있는데, 리액트는 하나의 요소가 추가되면 어디에 이 요소를 추가해야 하는지 찾아본다. 만약 keys가 없다면 일단 리스트의 제일 밑에 추가한다. 그 뒤에 해당 리스트와 연결되어 있는 데이터(배열)를 보고 데이터의 순서에 맞게 재배치를 진행하는데.... 이렇게 되면 성능상으로 안 좋아질 수 있다.
그래서 key라는 props를 부여해 리액트가 개별 아이템을 인식할 수 있도록 도와주는것 이다.
key가 아이템의 고유값으써 리액트는 이 값을 보고 하나하나의 요소를 구별해 낼 수 있으며 새로운 아이템을 추가되었을때 어느부분에 추가해야 하는지 바로 파악할 수 있게 된다.
2. 조건문의 다양한 활용
year 이라는 state로 filtering된 리스트를 값이 있을때는 출력시켜주고
값이 없을때는 값이 없다라는 문구를 출력시켜준다.
const Expenses = (props) => {
const [year, setYear] = useState("2020");
const filterChangeHandler = (selectedYear) => {
setYear(selectedYear);
};
const filteredExpenses = props.expenses.filter(
(expense) => expense.date.getFullYear().toString() === year
);
let expensesContent = <p>No expenses found.</p>;
if (filteredExpenses.length > 0) {
expensesContent = filteredExpenses.map((item) => (
<ExpenseItem
key={item.key}
title={item.title}
date={item.date}
amount={item.amount}
/>
));
}
return (
<Card className="expenses">
<ExpensesFilter selected={year} onChangeFilter={filterChangeHandler} />
{expensesContent}
</Card>
);
};
이 코드를 조금더 가독성이 있게 바꿔주려는데 리스트 출력 부분을 컴포넌트로 빼서 해주면 좋을꺼 같다.
const Expenses = (props) => {
const [year, setYear] = useState("2020");
const filterChangeHandler = (selectedYear) => {
setYear(selectedYear);
};
const filteredExpenses = props.expenses.filter(
(expense) => expense.date.getFullYear().toString() === year
);
return (
<Card className="expenses">
<ExpensesFilter selected={year} onChangeFilter={filterChangeHandler} />
<ExpenseList expenses={filteredExpenses} />
</Card>
);
};
밑의 부분은 우리가 조건에 따라 보여주는 부분이 이제 이 컴포넌트의 전체가 되었기 때문에 조건문의 활용을
이렇게도(비어있는 배열이라면 바로 값이 없다라는 스니펫을 보여주는 값을 리턴) 할 수 있다.
const ExpenseList = (props) => {
if (props.expenses.length === 0) {
return <h2 className="expenses-list__fallback">No expenses found.</h2>;
}
return (
<ul className="expense-list">
{props.expenses.map((item) => (
<ExpenseItem
key={item.key}
title={item.title}
date={item.date}
amount={item.amount}
/>
))}
</ul>
);
};
3. 동적 스타일
일반 스타일을 집어 넣을때는
style={'height: 10%'}
하지만 동적인 스타일을 위해서는 이중 중괄호가 필요하다.
const ChartBar = (props) => {
let barFillHeight = "0%";
if (props.maxValue > 0) {
barFillHeight = Math.round((props.value / props.maxValue) * 100) + "%";
}
return (
<div className="chart-bar">
<div className="chart-bar__inner">
<div
className="chart-bar__fill"
style={{ height: barFillHeight }}
></div>
</div>
<div className="chart-bar__label">{props.label}</div>
</div>
);
};