<수정 중 : 필터 부분 채우기>리액트 공부하기 - map(), filter() 을 활용한 반복 렌더링
오 ! 자바스크립트 할 때 열심히 했던 배열메소드 🧚♀️
1. map 복습하기
2. map()으로 컴포넌트 반복 렌더링
3. key란?
4.key를 사용하는 방법
5. filter 복습하기
6. 데이터 필터링. filter()가, map()과 함께 주로 사용 되는 이유
✨map() 빠르게 복습하기
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 콜백을 호출한 결과를 모아 새로운 배열을 반환. 이때 원본 배열은 변경되지 않는다!
const array = [1, 2, 3];
array.map((el, index, arr) => {
console.log(`arr의 요소:${el}, arr의 index:${index}, 순회하는 배열:${arr}`);
})
// arr의 요소:1, arr의 index:0, 순회하는 배열:1,2,3
// arr의 요소:2, arr의 index:1, 순회하는 배열:1,2,3
// arr의 요소:3, arr의 index:2, 순회하는 배열:1,2,3
- el : 처리할 현재 요소
- index : 처리할 현재 요소의 인덱스
- arr : map()을 호출한 배열
3개까지 인자 넣을 수 있는 것 기억하지 ?
아래 내용을 참고해봐도 좋아요 !
자바스크립트 공부하기 - 빌트인 생성자 배열 중 forEach(), map(), filter() 깊게 공부해보자
자주 쓰이는 배열 메소드 중, 세개가 개념이 비슷하고 헷갈린 것 같아서 정리의 필요성을 느꼈다.이전 글 참조하기 ! 🍑 자바스크립트 공부하기 - 빌트인 생성자 배열지난 기억 되짚고 가기...
creamymood.tistory.com
✨map() 메서드를 이용한 컴포넌트 반복하기
map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 콜백을 호출한 결과를 모아 새로운 배열을 반환합니다. 이때 원본 배열은 변경되지 않습니다.
import React from "react";
import ListItem from "./ListItem";
export default function App() {
const datas = [
{ id: "John", name: "John", age: 20 },
{ id: "Bob", name: "Bob", age: 30 },
{ id: "Jane", name: "Jane", age: 35 },
{ id: "Alice", name: "Alice", age: 29 },
];
return (
<div>
{datas.map((data) => (
// key에대한 설명은 아래에서 진행합니다.
<ListItem key={data.id} data={data} />
))}
</div>
);
}
datas 배열을 각 요소를 순회하며, ListItem 컴포넌트를 렌더링.
import React, { useState } from "react";
export default function App() {
// useState를 사용하여 datas 배열을 선언합니다.
const [datas, setDatas] = useState([
{ name: "John", age: 20 },
{ name: "Bob", age: 30 },
{ name: "Jane", age: 35 },
{ name: "Alice", age: 29 },
]);
return (
<div>
{datas.map((data) => (
<div>
{data.name} {data.age}
</div>
))}
</div>
);
}
→결과 화면
✨key 란?
위 예제를 보면 문제가 없어 보이지만, 개발자 도구/console 창을 열어보면 에러가 발생한 것을 볼 수 있어
에러를 확인해보면 유니크한 key prop가 필요하다고 한다.
map() 메서드 안에서 JSX 요소를 직접 사용할 때는 각 요소에 고유한 key prop이 필요하다 !
key prop은 React에서 배열을 렌더링할 때 각각의 항목을 식별하는 데 사용되는 속성이다.
이것은 리액트에게 각 항목이 고유하다는 것을 알려주는 역할을 함.
배열을 렌더링할 때 각 항목이 고유해야 하는 이유는 리액트의 동작방식과 성능 최적화와 관련이 있다.
❶리액트의 재조정
리액트는 Virtual DOM을 사용하여 UI를 빠르게 업데이트하는데, 이 때, 이전과 새로운 Virtual DOM을 비교하여 변경 사항을 식별하는 과정이 필요하다. 이 과정에서 각 항목에 고유한 식별자가 있으면 리액트는 효율적으로 변경된 항목만 업데이트할 수 있다 !
❷성능 최적화
만약 항목에 고유한 식별자가 없다면, 리액트는 전체 리스트를 다시 렌더링 하는 것으로 간주하여 성능 저하가 발생할 수 있음..
❸DOM 조작 및 관리
고유한 식별자를 가진 항목은 해당 DOM 요소를 조작하거나 관리할 때 유용하다. 예를 들어, 특정 항목을 선택적으로 업데이트하거나 제거할 때 고유한 식별자가 필요함
→결론적으로 key prop은 각각의 엘리먼트를 유일하게 식별하는 데 도움을 주고, 업데이트를 효율적으로 관리할 수 있도록 해준다.
이렇게 함으로써 애플리케이션의 성능을 최적화하고 사용자 경험을 향상시킬 수 있다!
✨key를 사용하는 방법
key를 선택하는 가장 좋은 방법은 리스트의 다른 항목들 사이에서 해당 항목을 고유하게 식별할 수 있는 문자열을 사용하는 것
대부분의 경우 데이터의 id를 key로 사용한다. 현재는 더미 데이터를 로컬에서 생성하고 있으므로 직접 id를 추가해보자
import React, { useState } from "react";
export default function App() {
// useState를 사용하여 datas 배열을 선언합니다.
const [datas, setDatas] = useState([
{ id: 1, name: "John", age: 20 },
{ id: 2, name: "Bob", age: 30 },
{ id: 3, name: "Jane", age: 35 },
{ id: 4, name: "Alice", age: 29 },
]);
return (
<div>
{datas.map((data, id) => (
<div key={id}>
{data.name} {data.age}
</div>
))}
</div>
);
}
✨filter() 빠르게 복습하기
filter() 메서드는 배열의 각각의 요소에 대해 콜백을 호출한 결과 true를 반환하는 모든 요소를 모아 새로운 배열을 반환. 이때 원본 배열은 변경되지 않는다!
const words = ["spray", "elite", "exuberant", "destruction", "present"];
const result = words.filter((el) => {
return el.length > 6;
});
console.log(result); // [ 'exuberant', 'destruction', 'present' ]
✨데이터 필터링, filter()가 주로 map()과 같이 사용되는 이유
예시 : people 데이터가 아래와 같을 때 profession이 ‘chemist’인 사람만 보여주고 싶다고 가정한 뒤,
이때 filter() 메서드를 이용해서 people 데이터를 필터링 해보자 !
const people = [
{
id: 0,
name: "라이언",
profession: "mathematician",
},
{
id: 1,
name: "어피치",
profession: "chemist",
},
{
id: 2,
name: "제이지",
profession: "physicist",
},
{
id: 3,
name: "춘식이",
profession: "chemist",
},
{
id: 4,
name: "콘",
profession: "astrophysicist",
},
];
import React from "react";
export default function App() {
const people = [```];
return (
<div>
<ul>
{people.filter((person) => (
<li>{person.profession === "chemist"}</li>
))}
</ul>
</div>
);
}
위 예제를 보면 문제가 없어 보이지만, 개발자 도구/console 창을 열어보면 에러가 발생한 것을 볼 수 있어
이 에러는 React가 JSX로 렌더링하는 동안 발생한다. 에러를 보면 객체는 React의 유효한 자식이 아니라고 한다. 이는 filter() 메서드 자체가 JSX를 반환하지 않기 때문이다 !
filter()라는 친구는, "얘 포함할까? 말까? " → "Yes!"or"No!" 이 대답만 알고 싶어하는 친구라, true / false만 중요하다.
하지만 JSX는 리액트가 화면에 보여줄 태그 인데, 즉, filter()는 이렇게 생긴 걸 보면… ❔❔❔
"이게 true야 false야? 나 그거만 알고 싶어!"
근데 JSX는 그런 걸 대답해줄 수 없지.
그래서 문제는?
너가 쓴 코드에서는:
people.filter(person => (
<li>{person.profession === "chemist"}</li>
))
이건 filter()한테 “이 사람 chemist야?” 라고 묻는 게 아니고,
그냥 <li>true</li> 혹은 <li>false</li>를 주는 거야.
근데 filter()는 그런 거 몰라... JSX 말고 그냥 true or false 달라고 했잖아! 😭
그래서 이렇게 해야해 !
people.filter(person => person.profession === "chemist")
이건 딱 true / false만 줘서, filter가 좋아하는 방식이야!
그리고 그 다음에 map()으로 만들어주면 완벽해! 👏🏻
import React from "react";
export default function App() {
const people = [
{
id: 0,
name: "라이언",
profession: "mathematician",
},
{
id: 1,
name: "어피치",
profession: "chemist",
},
{
id: 2,
name: "제이지",
profession: "physicist",
},
{
id: 3,
name: "춘식이",
profession: "chemist",
},
{
id: 4,
name: "콘",
profession: "astrophysicist",
},
];
const chemists = people
.filter((person) => person.profession === "chemist")
.map((chemist) => <li key={chemist.id}>{chemist.name}</li>);
return (
<div>
<ul>{chemists}</ul>
</div>
);
}
실제로 React에서 filter()는 거의 항상 map()이랑 같이 사용된다.
🍑 왜 같이 쓰냐고?
- filter()는 → 조건에 맞는 데이터만 추림
- map()은 → 그 데이터를 JSX로 바꿈
근데 꼭 map()이 아니더라도, filter()안에 JSX가 단독으로 들어갈 수 없어.
(왜냐하면 JSX는 true/false가 아니라 '화면에 보여주는 것'이니까!)
출처 : 오즈코딩스쿨, 구글링, 챗지피티, 공식문서