웹 페이지를 만들다 보면 동일한 구조의 데이터를 다룰 일이 많아진다. 예를 들어, 블로그 글 목록에서는 동일한 구조로 된 내용이 가득하다. 어떤 구조체를 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).
배열 항목을 필터링 하는 filter
배열에 적용 가능한 함수는 map
뿐만 아니라 다른 여러 함수들도 많다. 예를 들어 filter
를 생각해 볼 수 있다. filter
는 이름에서 볼 수 있듯 특정 조건에 따라 배열의 항목을 만들고 지우는 함수이다.
간단한 쇼핑몰을 만든다고 생각해 보자. 이 쇼핑몰에는 “판매중인 상품만 보기” 기능이 있다. 수 많은 데이터 중에서 품절 상태인 물건들은 보여주지 않으려고 한다. 이때 사용할 수 있는 것이 filter
이다.
필터 또한 마찬가지로 새로운 배열을 만들어 낸다. 즉, 기존 배열에 영향을 주지 않는다.
새로운 배열을 만들어 내기에, filter와 map을 계속해서 조합해 낼 수도 있다. 리턴 타입이 배열이기도 하고, 원래 배열에는 영향을 주지 않기 때문이다.
그 외에도 다양한 함수 존재
인터넷에 찾아보면 관련된 내용이 많기 때문에 일일이 설명하진 않지만, Reduce
(~Flatten
), FlatMap
등 많은 함수들이 있다. 컨테이너 타입을 축소할 경우 min
, max
, sum
과 같은 함수 또한 생각할 수 있다. terminally 함수까지 생각하면 forEach
또한 있다.
여기서 소개된 다양한 함수들은 side effect가 없는 함수이다. 즉, 함수의 실행 결과가 원래의 배열(컨테이너)에 영향을 주지 않는다. Terminally 함수 또한 자세히 들여다 보면 리턴이 Unit
일 뿐이다. 이러한 함수들을 조합하여 보다 풍부한 기능을 가진 페이지를 만들 수 있다.
답글 남기기