React는 동적인 웹 애플리케이션을 구축할 때 매우 유용한 자바스크립트 라이브러리로, 다양한 데이터를 효율적으로 관리하고 렌더링하는 데 중요한 역할을 한다. 이러한 과정 속에서, 배열 메소드의 활용은 매우 중요한 부분을 차지한다.
특히, map
, sort
, filter
와 같은 자바스크립트 배열 메소드들은 React에서도 그 중요성을 유지하며, 이러한 메소드들을 통해 데이터를 렌더링하고 원하는 방식으로 데이터를 조작하며, 사용자 경험을 향상시키는 데 필수적인 역할을 하게 된다.
오늘은 이러한 배열 메소드를 React에서 어떻게 활용하는지, 그리고 이를 통해 어떠한 장점을 얻을 수 있는지에 대해 학습해보자.
React에서 배열 메소드를 활용하는 방법에 대해서 다양한 예제를 통해 살펴보고자 한다.
예제를 위해, 아래와 같은 id, name, types 프로퍼티가 있는 포켓몬 데이터를 가진 pokemon.json 파일을 mock파일을 사용할 예정이다.
[
{
"id": 1,
"name": "리자몽",
"types": [
"불꽃",
"비행"
]
},
...
]
먼저, React에서 배열을 렌더링하는 기본적인 방법부터 살펴보자. map 메소드
를 사용하면 간단히 배열의 각 요소를 원하는 형태의 React 엘리먼트로 변환 가능하다.
아래 예제에서는 map 메소드를 사용하여 pokemons 배열의 각 요소를 Pokemon 컴포넌트로 변환하고 있다.
코드를 살펴보면, map의 콜백 함수에서 JSX로 작성된 값을 리턴하고 있는 모습을 볼 수 있는데, 이런 식으로 배열을 렌더링하는 방식은 많은 데이터를 보여줄 때 꼭 필요한 방법이니 숙지하도록 하자.
import items from './pokemons';
function Pokemon({ item }) {
return (
<div>
No.{item.id} {item.name}
</div>
);
}
function App() {
return (
<ul>
{items.map((item) => (
<li key={item.id}>
<Pokemon item={item} />
</li>
))}
</ul>
);
}
export default App;
JSX의 중괄호 안에서 map 함수를 사용하는 것이 일반적이지만, 다른 방식으로도 구현할 수 있다. 예를 들어서 아래처럼 renderedItems 라는 변수에 map의 결과를 지정해도 똑같이 렌더링 하게 되는데, 이는 renderedItems 의 계산된 값이 결국 리액트 엘리먼트의 배열이기 때문이라는 점을 이해하자.
// .. 동일
function App() {
const renderedItems = items.map((item) => (
<li key={item.id}>
<Pokemon item={item} />
</li>
));
return (
<ul>
{renderedItems}
</ul>
);
}
export default App;
이제, 배열을 원하는 순서대로 정렬하는 방법에 대해 알아보고자 한다. sort 메소드를 사용하면 배열의 요소를 쉽게 정렬할 수 있다.
아래 예제에서는 sort 메소드를 사용하여 포켓몬을 ID 기준으로 오름차순 및 내림차순으로 정렬한다. 이때, 주의할 점은 sort 메소드가 원본 배열을 변경한다는 점이다. 따라서 원본 배열을 복사한 후 정렬하는 것이 권장된다.
import { useState } from 'react';
import items from './pokemons';
function Pokemon({ item }) {
return (
<div>
No.{item.id} {item.name}
</div>
);
}
function App() {
const [direction, setDirection] = useState(1);
const handleAscClick = () => setDirection(1);
const handleDescClick = () => setDirection(-1);
const sortedItems = items.sort((a, b) => direction * (a.id - b.id));
return (
<div>
<div>
<button onClick={handleAscClick}>도감번호 순서대로</button>
<button onClick={handleDescClick}>도감번호 반대로</button>
</div>
<ul>
{sortedItems.map((item) => (
<li key={item.id}>
<Pokemon item={item} />
</li>
))}
</ul>
</div>
);
}
export default App;
마지막으로, filter 메소드를 사용하여 특정 조건을 만족하는 요소만 남기는 방법을 알아보자. 배열 메소드 중 filter 와 배열형 스테이트를 활용하면 삭제 기능을 간단히 구현할 수 있다.
import { useState } from 'react';
import mockItems from './pokemons';
function Pokemon({ item, onDelete }) {
const handleDeleteClick = () => onDelete(item.id);
return (
<div>
No.{item.id} {item.name}
<button onClick={handleDeleteClick}>삭제</button>
</div>
);
}
function App() {
const [items, setItems] = useState(mockItems);
const handleDelete = (id) => {
const nextItems = items.filter((item) => item.id !== id);
setItems(nextItems);
};
return (
<ul>
{items.map((item) => (
<li key={item.id}>
<Pokemon item={item} onDelete={handleDelete} />
</li>
))}
</ul>
);
}
export default App;
Key는 React가 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 돕는다. 또한, key는 엘리먼트에 안정적인 고유성을 부여한다. 만약 key가 없을 경우, React는 재사용하는 컴포넌트를 정확히 식별하지 못해 예상치 못한 상태 관리 문제가 발생할 수 있다.
이 같은 이유로, 각 요소를 렌더링 할 때는 key Prop을 반드시 내려줘야 하는데, 이때 가장 바깥쪽에 있는 (최상위) 태그에다가 key Prop을 지정하면 된다.
포켓몬 이름처럼(참고로 포켓몬 이름은 고유하다) 각 데이터를 구분할 수 있는 고유한 값이면 무엇이든 key 로 활용해도 상관없지만, 주로 id를 key값으로 활용하는 경우가 많으니 이 부분도 참고하자.
import items from './pokemons';
function Pokemon({ item }) {
return (
<div>
No.{item.id} {item.name}
</div>
);
}
function App() {
return (
<ul>
{items.map((item) => (
<li key={item.name}>
<Pokemon item={item} />
</li>
))}
</ul>
);
}
export default App;
위와 같은 내용을 통해 React에서 배열 메소드를 활용하여 렌더링, 정렬, 삭제와 같은 기능을 구현하는 방법을 살펴보았다.
map을 사용한 렌더링, sort를 통한 배열 정렬, 그리고 filter를 이용한 삭제 기능 구현은 React 개발의 기본이자, 중요한 요소이다. 각 메소드의 올바른 사용법을 이해하고, 특히 React에서 key prop의 중요성을 인식하는 것은 잊지말자.
이번 학습을 통해 느낀 점은, React와 같은 현대적인 프레임워크를 사용할 때, 자바스크립트의 기본적인 배열 메소드를 어떻게 활용하는지 이해하는 것은 매우 중요합니다는 것이다. 오늘의 학습을 통해 다양한 데이터를 보다 유연하게 다루고, 효율적이고 안정적인 UI를 구성하는 연습을 지속해 나가보자.