실무 전용 반복문(map, filter)

huni_·2022년 7월 5일
0

React

목록 보기
16/57

실무에 나가시면 for문 보다는 map과 filter 를 더 많이 사용하게 됩니다.

map과 filter모두 배열의 내장함수 이기때문에 사용하실때는 배열과 함께 사용해야 합니다.

1. map

map은 배열의 원소를 일괄적으로 변형시킬 때 사용하기 좋습니다.

1-1 . map의 사용방법

const classmate = ["철수","영희","훈이"]

classmate.map((item)=>(item+"어린이"))
=> (3)["철수어린이","영희어린이","훈이어린이"]

map안에서 사용되는 item은 classmate의 원소들이 들어갈 파라미터(매개변수) 입니다.
파라미터의 네이밍은 마음대로 정하셔도 무방합니다.

객체가 원소인 배열에서도 map을 이용해 객체를 가공해보도록 하겠습니다.

const classmate = [
	{name: "철수"},
	{name: "영희"},
	{name: "훈이"}]

//item.name => "철수","영희","훈이"
//school 속성을 일괄적으로 추가해주도록 하겠습니다.

classmate.map((item)=>({name : item.name + "어린이", school : "떡잎유치원"}))
=> (3)[
	{name : "철수어린이",school : "떡잎유치원"},
	{name : "영희어린이",school : "떡잎유치원"},
	{name : "훈이어린이",school : "떡잎유치원"}
]

레벨업!

💡 화살표 함수에서 소괄호를 생략이 가능할까요?
→ 정답은 상황에 따라 가능하다 입니다.
본문(뒤의 괄호 안에 적히는 코드)이 한줄이라면 생략이 가능합니다.

그렇다면 언제 생략이 불가능 할까요?
리턴값이 객체인 경우생략이 불가능 합니다.
중괄호가 없어지면 객체의 중괄호가 함수의 중괄호가 되어버립니다.
따하서 리턴값이 객체일 경우엔 생략하시면 안됩니다.

💡 화살표 함수 () ⇒ {} vs () ⇒ ()
→ 소괄호 ()로 감싸진 부분이 return
됩니다.(return문을 작성하지 않아도 리턴 됩니다.)
반면 중괄호{}로 감싸진 함수는 return문이 없다면 리턴값을 반환하지 않습니다.

1-2 . HTML 과 연결하기

실제 프로젝트에서는 컴포넌트의 리턴값안에서 많이 사용하게 됩니다.

map을 리턴값 안에서 사용하기위해 {}으로 감싸서 사용합니다.(return 안에 자바스크립트를 가지고 오기 위해서 {}을 사용하는 것 입니다.)

// RenderMap 컴포넌트
const RenderMap = ()=>{
const classmate = ["철수","영희","훈이"]

	return(
		//중괄호를 이용해 자바스크립트를 컴포넌트의 return값 안으로 데리고 들어온 것 입니다.
  		//리턴되어야 할 값이 한줄이기때문에 괄호생략이 가능합니다.
		{classmate.map( (item)=> <div>{item}어린이</div> )}
	) 
}
export default RenderMap

2. filter

filter는 이름 그대로 배열의 원소를 필터링 해주는 메서드 입니다.

filter는 필터링 할 조건으로 객체 혹은 배열의 각원소를 검사하여 그 조건에 맞는 원소들만 결과값으로 도출해 줍니다.

2-1. filter의 사용방법

const num = [1,2,3,4,5,6,7,8,9,10]

num.filter((item)=>(item<=8))
=> (8) [1, 2, 3, 4, 5, 6, 7, 8]

filter 안에서 사용되는 item 역시 배열의 원소가 들어갈 파라미터 입니다.

💡 map과 filter의 결과물 차이점
map은 배열의 길이만큼 값이 나오지만, filter는 조건에 따라 배열의 길이보다 적게 나옵니다.


map의 index를 key로 사용시 발생하는 문제점

react 공식 문서에 나오는 key와 id 링크
여기까지 오신 분들은 아마 map을 통해서 데이터를 한 번에 뿌리는 것까지 오셨을 겁니다.
그런데 map을 하면 한 가지 문제점이 발생합니다.
간단한 예제를 보겠습니다.
리스트를 map을 통해 한 번에 보여주고 있습니다.

import { Test } from '../../src/test2';

export default function Test2() {
	const List = ['사과', '딸기', '바나나'];

	return (
		<>
			{List.map((data) => (
				<Test>{data}</Test>
			))}
		</>
	);
}

그런데 말입니다.
console.log()가 이상합니다.

오류 메시지를 해석해보겠습니다.
음.. 각각의 child은 unique한 "key"가 있어야 한다는 것 같네요.
왜 이런 메시지가 뜨는 것일까요?


React에서 Key가 필요한 이유

해당 경고는 React가 어떤 요소를 변경, 추가, 삭제할지 식별하기 위함입니다. key가 없는 경우에는 가상 DOM을 비교하는 과정에서 순차적으로 비교하며 변화를 감지합니다. key가 있다면, 이 값을 사용하여 어떤 것이 수정이 됐는지 빠르게 감지할 수 있습니다.

(이 부분은 react가 브라우저에 그려지는 과정, 가상 DOM에 대해 공부하시면 더 빠르게 이해하실 수 있습니다.)

위의 설명을 짧게 보충한다면, React에서는 기존 데이터와 바뀐 데이터를 비교하여 바뀐 부분을 화면에 그려줍니다.

여기서 비교할 때 고유한 Key값이 없다면 모든 데이터를 비교해야 하지만, Key가 있으면 Key값만 비교하여 Key가 추가 됐는지, 삭제 됐는지만 비교하여 불필요한 비교나 렌더링을 없애줍니다.

그러기 위해 key는 안정적인 고유성을 부여하기 위해 중복되는 값이 아닌 것으로 지정해줘야 합니다. (만약 key를 지정하지 않을 경우 자동으로 index를 키로 사용합니다. 하지만 이는 좋은 방법이 아니라 경고가 뜹니다.)

그래서 React 공식 문서에서도 Key 값으로 id를 주는 것을 추천합니다.

(아래는 예제이기 때문에 id가 없지만 예시로 넣어두었습니다.)

import { Test } from '../../src/test2';

export default function Test2() {
	const List = ['사과', '딸기', '바나나'];

	return (
		<>
			{List.map((data) => (
				<Test **key={id}**>{data}</Test>
			))}
		</>
	);
}

앞으로 여러분의 효율적인 React를 위해 map을 쓰실 때는 꼭 id값을 적어주세요.


Index를 Key로 줘도 괜찮은 상황

index를 key로 줘도 괜찮은 상황이 있습니다. 아래 3가지 조건을 만족하면 됩니다.

  1. 정적인 데이터. 계산되지 않고 변경되지 않는 데이터
  2. map에 있는 모든 데이터에 id가 없을 경우
  3. 데이터가 재정렬되거나 필터링 되지 않는 경우. (계속 그 자리 그대로)

위의 3가지를 만족한다면 index를 key로 사용해도 안전합니다.

하지만 서버에서 받아오는 데이터라면 그럴리 없겠죠?

index와 key에 대한 설명 링크

map과 for문 중 어떤게 더 빠른가요?

map을 사용하게 되면 map안에 있는 요소들이 동시에 작동하게 됩니다.
외부 api를 사용할 경우 map을 사용하는게 보다 빠릅니다.
나중에 promiseAll을 배우게 됩니다. 훨씬 더 빨라집니다.
for문은 한개씩 끝나기를 기다렸다가 다음 반복문을 실행시킵니다.

profile
FrontEnd Developer

0개의 댓글