조건부 렌더링
컴포넌트 내부에 조건문으로 JSX를 동적으로 표현할 수 있다. (if문, 삼항 연산자, 논리 연산자 &&)
if문
function Item({ name, isPacked }) {
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
}
export default function PackingList() {
return (
<section>
<h1>Sally Ride's Packing List</h1>
<ul>
<Item
isPacked={true}
name="Space suit"
/>
<Item
isPacked={true}
name="Helmet with a golden leaf"
/>
<Item
isPacked={false}
name="Photo of Tam"
/>
</ul>
</section>
);
}
특정 조건일 땐 아무것도 반환하고 싶지 않다면 null 을 사용하면 된다.
if (isPacked) {
return null;
}
return <li className="item">{name}</li>;
하지만 이 방법은 일반적이진 않는다. null 대신 조건부에서 제외시키는 방법으로 사용하는 것이 더욱 일반적이다.
삼항 연산자
if (isPacked) {
return <li className="item">{name} ✔</li>;
}
return <li className="item">{name}</li>;
위 코드는 딱 보기에도 중복된다. 문제가 되는 건 아니지만 보통 개발자들은 중복을 싫어하기 때문에 이런 경우 삼항 연산자를 사용하여 아래와 같이 사용한다.
return (
<li className="item">
{isPacked ? name + ' ✔' : name}
</li>
);
논리 연산자 && (AND)
리액트 컴포넌트에서 어떤 조건이 true 일 때 JSX를 렌더링하고, false 일 땐 아무 동작도 안 하기 위해서 && 연산자를 사용한다.
return (
<li className="item">
{name} {isPacked && '✔'}
</li>
);
Javascript에서 && 연산자는 왼 쪽이 true 일 경우 오른 쪽을 반환한다. 만약 왼 쪽이 false일 경우 표현식 전체가 false가 된다. 이렇게 되면, 리액트는 아무것도 렌더링 하지 않는다.
** 왼 쪽에 숫자 0을 넣으면 안 된다. 0이면 false로 인식하는 게 아니라 리액트는 말그래도 0으로 인식하기 때문에 0을 렌더링하게 된다. 무조건 boolean 형식으로 만들어주어야 한다.
변수에 조건부로 JSX 할당하기
제일 많이 사용하는 방법이다.
function Item({ name, isPacked }) {
let itemContent = name;
if (isPacked) {
itemContent = name + " ✔";
}
return (
<li className="item">
{itemContent}
</li>
);
}
코드로만 따지면 가장 길지만 가장 유연해서 제일 많이 사용한다.
목록 렌더링
배열에서 데이터 렌더링하기
<ul>
<li>Creola Katherine Johnson: mathematician</li>
<li>Mario José Molina-Pasquel Henríquez: chemist</li>
<li>Mohammad Abdus Salam: physicist</li>
<li>Percy Lavon Julian: chemist</li>
<li>Subrahmanyan Chandrasekhar: astrophysicist</li>
</ul>
위 HTML 소스를 보면 컴포넌트는 동일하고 안의 data만 바뀐다. 해당 데이터를 자바스크립트의 객체와 배열에 저장하고 map을 사용하여 컴포넌트 목록을 렌더링할 수 있다.
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
export default function List() {
const listItems = people.map(person =>
<li>{person}</li>
);
return <ul>{listItems}</ul>;
}
위 코드는 문제 없이 렌더링은 되지만 콘솔 창에 warning이 뜬다. key 가 없기 때문이다. 이 문제는 아래서 다시 다뤄보도록 한다. (Warning: Each child in a list should have a unique “key” prop.)
Key
각 항목(item)에는 key가 있어야 하는데, key는 배열 내에서 유니크한 문자열 또는 숫자여야 한다.
key는 각 컴포넌트가 어떤 배열의 항목에 해당하는지 리액트에게 알려주어 나중에 매칭할 수 있도록 한다. 배열이 이동, 삽입, 삭제될 경우에 유용하다.
key를 코드 내에서 생성하기 보다는 데이터에 포함 시켜야 한다.
import { people } from './data.js';
import { getImageUrl } from './utils.js';
export default function List() {
const listItems = people.map(person =>
<li key={person.id}>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
return <ul>{listItems}</ul>;
}
export const people = [{
id: 0, // Used in JSX as a key
name: 'Creola Katherine Johnson',
profession: 'mathematician',
accomplishment: 'spaceflight calculations',
imageId: 'MK3eW3A'
}, {
id: 1, // Used in JSX as a key
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
accomplishment: 'discovery of Arctic ozone hole',
imageId: 'mynHUSa'
}, {
id: 2, // Used in JSX as a key
name: 'Mohammad Abdus Salam',
profession: 'physicist',
accomplishment: 'electromagnetism theory',
imageId: 'bE7W1ji'
}, {
id: 3, // Used in JSX as a key
name: 'Percy Lavon Julian',
profession: 'chemist',
accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
imageId: 'IOjWm71'
}, {
id: 4, // Used in JSX as a key
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
accomplishment: 'white dwarf star mass calculations',
imageId: 'lrWQx8l'
}];
export function getImageUrl(person) {
return (
'https://i.imgur.com/' +
person.imageId +
's.jpg'
);
}
그렇다면 key는 보통 어디서 가지고 올까?
1. 데이터베이스의 데이터: 주로 ID를 사용한다.
2. 로컬에서 생성된 데이터: DB를 안 쓰는 앱같은 경우엔 incrementing counter, crypto.randomUUID(), uuid 패키지 등을 사용할 수 있다.
key 규칙
1. sibling 사이에서는 고유해야 한다. 즉 다른 배열에는 동일한 key를 사용해도 된다.
2. key는 변경되지 않아야 한다.
리액트에서 key가 필요한 이유
쉽게 생각하면 폴더 내 파일 이름을 key라고 생각하면 된다. key가 없으면 리액트는 index를 key 삼아 사용하지만 이는 배열이 변경됨에 따라 계속 바뀐다. 그래서 가끔 알 수 없는 버그를 일으킬지도..? (공식 문서 왈)
그리고 key를 즉석에서 생성할 경우 (예를 들어 key = { Math.random() }) 랜더링 할 때마다 key가 바뀌고, 그 말은 즉, 매번 모든 컴포넌트와 DOM이 다시 생성된다는 말이다. 이는 속도를 느려지게 하고 사용자가 입력한 데이터가 손실될 수도 있다.
또한 key는 prop에 포함되지 않는다. 따라서 key가 필요할 경우 <Profile key={id} userId={id} />와 같이 따로 지정해주어야 한다.
'공부기록 > 리액트' 카테고리의 다른 글
[REACT] JSX에서 Javascript 사용하기 - 공식 문서랑 같이 공부하기 시리즈5 (0) | 2023.11.15 |
---|---|
[REACT] JSX란 - 공식 문서랑 같이 공부하기 시리즈4 (0) | 2023.11.15 |
[REACT] 컴포넌트에 props 전달하기 - 공식 문서랑 같이 공부하기 시리즈3 (0) | 2023.11.14 |
[REACT] Components Import & Export - 공식 문서랑 같이 공부하기 시리즈2 (0) | 2023.11.14 |
[REACT] Components - 공식 문서랑 같이 공부하기 시리즈1 (0) | 2023.11.14 |