React – Map등을 이용한 배열 표시 (세미나 자료 #2)

웹 페이지를 만들다 보면 동일한 구조의 데이터를 다룰 일이 많아진다. 예를 들어, 블로그 글 목록에서는 동일한 구조로 된 내용이 가득하다. 어떤 구조체를 A라고 했을때, [A, A, A, A ···]와 같은 형태로 쭈우우욱 있는것을 배열(또는 목록)이라고 한다. 이 목록을 표시하는 방법을 다루고자 한다. 이 내용은 많은 글에서 다루고 있기 때문에, 핵심적인 내용만 다루려고 한다.

JSX 떠올리기

저번 글에서 보았던 이미지를 표시하는 컴포넌트 함수 코드를 생각해 보자. 이 코드에서 “이미지를 표시”하는 코드는 8번째 줄이다. variable 의 값에 적힌 주소를 받아온다.

그러면 이번에 여러개의 이미지를 표시하는 페이지를 만들어 보자.

들어가기 전에 Statement vs Expression
Expression은 식이라고 부른다. 즉, 해당 코드들이 하나의 값으로 바뀔 수 있다. 예를들어, 5 + 6은 식이다. 이것은 11로 계산 될 수 있다. add(max(10, 20), 50) 과 같은 코드 또한 식이다. 이것들 모두 하나의 값으로 계산 될 수 있다.
그러나 Statement는 그렇지 않다. ‘문장’이라고 번역하긴 하는데, 필자는 Statement를 그 자체로 읽어야 한다고 생각한다. 5 + 6; 이라는 코드 실행시 세미콜론에 의해 값이 빠져나오지 않는다. add(max(10, 20), 50); 또한 세미콜론을 붙이는 순간, 그저 그자리에서 계산이 되고 끝이 난다. (계산 값이 나오진 않는다)

좀 더 쉽게 이야기 해서, Expression은 연산 결과가 있지만 Statement는 연산 결과가 없다. 대부분의 statement는 side-effect로서 다른곳에 영향을 주므로서 연산 결과를 내놓는다.

배열 내부의 값을 변화시키는 Map

React는 함수의 결합으로 DOM Tree를 만든다고 했었다. 배열을 다룰때도 마찬가지 이다. 배열 또한 함수의 결합으로 이루어진다. 대부분의 경우 아래와 같이 map을 사용할 것이다:

7번째 줄이 핵심이다. imgs라는 배열의 각 항목을 <img src={img_src} /> 으로 바꾸는 기능을 한다. map은 컨테이너 내의 값을 어떤 함수를 통해 변환한다. 주의할 것은 배열 내부의 항목에 각각 Img 함수가 적용되며, 그 결과로 새로운 배열이 만들어 진다는 것이다. 즉, 아무리 map을 적용해도 기존 배열에는 영향이 없다.

위의 코드에서 imgs 내부의 항목 a, b, c, d, e가 각각 Img(img_src)의 파라메터로 들어가서 연산된다. 그리고 함수의 결과값이 반영된 새로운 배열이 생겨난다.

개념으로 따지자면 map은 컨테이너(=배열) 내부의 값(=각 원소)에 함수를 적용하는 함수이다. 여기서는 컨테이너가 배열이지만, Result, Option, 그 외 여러가지에 적용될 수 있다. 이 경우에도 컨테이너 내부 항목에 함수를 적용한다.

위의 코드에서는 배열에 map을 사용했기 때문에 배열의 각 항목에 함수를 적용한 효과를 보인다. React에서 map을 쓸 때 자주 헷갈려 하는 부분이map자체는 배열 내부의 값을 변환만 해 준다는 점이다. map이 직접적으로 Virtual DOM까지 만들어 주는것은 아니다.

다시 말해서, [a, b, c, d].map(v => <img src=v />)[<img src=a />, <img src=b />, <img src=c />, <img src=d />] 로의 변환까지만 해 준다. 이 배열을 React가 순환 하면서 Virtual DOM Tree에 집어 넣는다(flatten).

map 적용시 위와 같은 코드가 된다

배열 항목을 필터링 하는 filter

배열에 적용 가능한 함수는 map 뿐만 아니라 다른 여러 함수들도 많다. 예를 들어 filter를 생각해 볼 수 있다. filter는 이름에서 볼 수 있듯 특정 조건에 따라 배열의 항목을 만들고 지우는 함수이다.

간단한 쇼핑몰을 만든다고 생각해 보자. 이 쇼핑몰에는 “판매중인 상품만 보기” 기능이 있다. 수 많은 데이터 중에서 품절 상태인 물건들은 보여주지 않으려고 한다. 이때 사용할 수 있는 것이 filter이다.

필터 또한 마찬가지로 새로운 배열을 만들어 낸다. 즉, 기존 배열에 영향을 주지 않는다.

새로운 배열을 만들어 내기에, filter와 map을 계속해서 조합해 낼 수도 있다. 리턴 타입이 배열이기도 하고, 원래 배열에는 영향을 주지 않기 때문이다.

map을 이용해서 각 항목에 e를 붙이고 -> e의 갯수가 2개 초과인 항목만 -> ‘결과값: ‘ 이라는 글자를 붙여서 출력

그 외에도 다양한 함수 존재

인터넷에 찾아보면 관련된 내용이 많기 때문에 일일이 설명하진 않지만, Reduce(~Flatten), FlatMap등 많은 함수들이 있다. 컨테이너 타입을 축소할 경우 min, max, sum과 같은 함수 또한 생각할 수 있다. terminally 함수까지 생각하면 forEach또한 있다.

여기서 소개된 다양한 함수들은 side effect가 없는 함수이다. 즉, 함수의 실행 결과가 원래의 배열(컨테이너)에 영향을 주지 않는다. Terminally 함수 또한 자세히 들여다 보면 리턴이 Unit일 뿐이다. 이러한 함수들을 조합하여 보다 풍부한 기능을 가진 페이지를 만들 수 있다.

text를 filter로 한번 거른 후, map을 이용하여 HTML(JSX)로 변환한 모습

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

댓글을 작성하기 위해 아래의 숫자를 입력해 주세요. *Captcha loading…