스마트웹앱콘텐츠전문가

프론트엔드 실무에서 자주 쓰는 map() + ... 연산자 패턴 총정리

9D4U 2025. 4. 17. 12:38
728x90
반응형

현대 웹 개발에서는 사용자와 동적으로 상호작용하는 UI가 필수입니다.

특히, Vue.js와 같은 프론트엔드 프레임워크를 사용하면 ref 객체와 computed, watch 등을 통해 반응형 데이터를 쉽게 다룰 수 있습니다.

 

이번 글에서는 Vue의 ref로 정의된 배열 데이터를 기반으로, 동적으로 테이블 헤더 객체를 구성하는 방법을 알아보겠습니다.

 

 

 

 


문제 정의

 

Vue에서 ref<T[]>([])로 선언된 배열 items를 기반으로 테이블 데이터를 그리고, 이 데이터와 관련된 헤더 영역도 함께 구성하려는 요구가 종종 발생합니다. 예를 들어, 다음과 같은 구조를 생각해볼 수 있습니다:

 

const items = ref<T[]>([]);
const dataList = items.value;

 

dataList가 존재하고,

그 길이가 0보다 클 경우에만 특정 처리(예: 총계 row 생성)를 하고 싶다면 아래처럼 작성할 수 있습니다:

 

if (dataList.length > 0) {
  getTotalRows(tableDatas, headerTotal);
}

 

이처럼 배열 길이를 체크해 조건문을 작성하면 불필요한 연산을 방지할 수 있어 성능 면에서도 이점이 있습니다.

 

 

 

 

 


동적으로 헤더 객체 배열 구성하기

 

데이터 테이블을 구성할 때, 헤더 부분도 데이터 기반으로 유연하게 변경되기를 원하는 경우가 많습니다. 예를 들어, 다음과 같은 배열을 기반으로 각 항목을 헤더로 사용하려면 어떻게 해야 할까요?

 

headerPeriod.value?.gridHeadList = ["1월", "2월", "3월"];

 

이 배열을 다음과 같은 형태로 객체화하고 싶다면?

[
  { headerTitle: "1월", colSpan: 2 },
  { headerTitle: "2월", colSpan: 2 },
  { headerTitle: "3월", colSpan: 2 }
]

 

자바스크립트의 map() 함수를 사용하면 매우 간단하게 구현할 수 있습니다.

 

 

 

 

 


map() 함수와 Spread Operator 활용법

 

아래는 map()과 spread operator (...)를 이용해 동적으로 헤더 배열을 구성한 코드 예시입니다:

 

const headerGridHeadListObj = [
  { headerTitle: glossaryWord("9000001067"), colWidth: 11 },  // total
  ...headerPeriod.value?.gridHeadList.map((item) => ({
    headerTitle: item,
    colSpan: 2
  })) || []
];

 

코드 해설

 

  • map()은 gridHeadList 배열의 각 요소(item)를 원하는 형식의 객체로 변환합니다.
  • ...(spread operator)는 map() 결과인 배열을 바깥 배열의 개별 요소로 풀어줍니다.
  • || []는 headerPeriod.value?.gridHeadList가 undefined일 경우를 대비한 fallback 처리입니다.

 

이 코드를 실행하면 최종적으로 다음과 같은 결과를 얻게 됩니다:

 

[
  { headerTitle: "합계", colWidth: 11 },
  { headerTitle: "1월", colSpan: 2 },
  { headerTitle: "2월", colSpan: 2 },
  { headerTitle: "3월", colSpan: 2 }
]

 

 

 

 

 

반응형

 

 

 


자주 하는 실수: 배열 안에 배열 넣기

 

 

많은 개발자들이 실수로 아래처럼 작성하는 경우가 있습니다:

 

const wrongHeader = [
  { headerTitle: "합계", colWidth: 11 },
  headerPeriod.value?.gridHeadList.map(item => ({ headerTitle: item, colSpan: 2 }))
];

 

이렇게 하면 headerPeriod.value?.gridHeadList.map(...)이 배열로 들어가기 때문에, 결과는 배열 안에 배열이 되는 잘못된 구조입니다.

 

✅ 정답은?
반드시 ... spread 연산자를 사용하여 배열을 풀어서 넣어야 합니다.

 

 

 

 


Optional Chaining과 Fallback 처리

 

 

JavaScript에서 optional chaining (?.)을 사용하면, null이나 undefined 값이 접근 시 오류를 방지할 수 있습니다. 여기에 || []와 같이 fallback 값을 제공하면 안전성과 안정성을 동시에 확보할 수 있습니다:

 

...headerPeriod.value?.gridHeadList.map(...) || []

 

 

 

 

 


 

 

 

이러한 코딩 패턴은 다음과 같은 상황에서 매우 유용합니다:

  • Vue.js에서 동적으로 데이터를 바탕으로 테이블을 구성할 때
  • 외부 API 데이터에 따라 UI가 달라져야 할 때
  • 가변적인 컬럼 구조를 가진 엑셀 스타일 테이블을 만들 때

Spread operator와 map() 함수는 JavaScript에서 매우 자주 쓰이며, 위와 같이 안전하게 결합하면 가독성도 좋고 에러도 방지할 수 있습니다.

 

728x90