자바스크립트에서 return 문을 정의하지 않은 함수의 default return 값은 undefined다. 입력값을 받아서 로직을 거쳐 출력값을 반환하는 함수라는 녀석에서 굉장히 기본적인 상식이지만 이 기본을 잊어서 곤혹을 겪는 경우가 종종 있다.
이와 비슷하게 오늘 쇼핑몰 장바구니 기능 구현 과제를 하다가 array.push()의 반환값 때문에 어처구니 없는 에러를 겪었다.
배열의 각종 메소드들은 for loop나 그밖의 다른 방법 등으로 배열을 순회하면서 각종 조건문을 걸어주면 어지간하게 다 구현할 수 있다. 하지만 메소드를 쓰면 그안의 로직은 알 바 아니고 내가 하고 싶은 일에만 집중할 수 있어서 엄청나게 편리하다. 명령형(또는 절차형)이 아닌 선언형 프로그래밍의 이점이라고 할 수 있다. 거기에 더해 코드 타이핑이 줄어드는 이점도 있다. (중요⭐️ ⭐️ ⭐️ ) 특히 배열 메소드들은 다음의 예시처럼 쭉 연달아서 쓸 수 있는 경우가 많다.
const renderItems = items.filter(
(el) => cartItems.map((el) => el.itemId).indexOf(el.id) > -1
);
장바구니에 담긴 상품 아이템 컴포넌트의 수량이 변경될 수 있도록 하는 함수의 코드를 작성면서 다음과 같은 의사 코드를 짰다.
1. 변경된 수량을 반영한 새로운 아이템 객체를 만든다.
2. 장바구니에 담긴 기존 아이템 목록 중에서 수량이 변경된 아이템을 찾아내 제거한 다음, 새로운 아이템을 추가한다.
3. 장바구니에 담긴 아이템 목록을 상태변경함수를 호출해 갱신한다.
const newCartItem = { itemId, quantity };
const newCartItems = cartItems.filter((el) => el.itemId !== itemId).push(newCartItem);
setCartItems(newCartItems);
...결과는?
콘솔창이 온통 붉어졌고 화면은 아예 통째로 사라졌다 ㅋㅋㅋㅋㅋ
filter와 push를 연속해서 쓴 두 번째 라인을 다음과 같이 분리해주면 코드는 정상적으로 동작했다.
const newCartItems = cartItems.filter((el) => el.itemId !== itemId);
newCartItems.push(newCartItem);
대체 뭐가 문제인지 찬찬히 들여다보니 filter와 push를 이어붙인 코드에서 newCartItems는 내가 원하는 배열이 아니라 단순한 숫자값이었다. push 메소드의 리턴값은 호출한 배열의 새로운 length 값이기 때문이었다...!
배열에 새로운 데이터를 push해서 넣을 때는 보통 push 이후에 배열에 데이터가 잘 담겼는지만 확인했지 push의 리턴값 자체를 활용해서 뭘 해본 기억이 없다. push, pop 메소드를 맨처음 배울 때 push의 리턴값에 대해 들어본 기억이 어렴풋이 나는 것도 같지만... 제거한 요소를 반환하는 pop 메소드에 비해 push의 리턴값에 대해 이제까지 크게 신경을 써본 적이 없었다. 그러다 만난 오늘의 복병... 😇
레퍼런스 코드를 보니 기존 장바구니 목록에서 수량을 변경해 주고 싶은 아이템만 찾아서 변형하는 map 메소드를 쓰는 더욱 간단한(?) 방법이 있었다. 배열 내장 메소드를 처음 배울 때 데이터 핸들링시 map과 reduce를 자주 쓴다는 강사 분의 말을 무슨 얘기인지 하나도 모른면서 그저 필기만 해놨었는데, 그 말의 의미를 이제서야 조금씩 알아가고 있다.
'돌멩이 하나 > 에러는 미래의 연봉' 카테고리의 다른 글
코드에 GitHub access token이 포함된 상태로 commit을 하면 어떻게 될까 (0) | 2023.01.31 |
---|---|
[React] useEffect hook에서 async/await 쓰는 방법 (0) | 2023.01.09 |
[React] form 데이터 서버에 전송하기 (0) | 2022.12.18 |
export와 import : 로컬 vs. 서버 (0) | 2022.12.04 |
[React] map() 메소드로 여러 개의 html 엘리먼트 표시할 때 JSX key 속성과 싸운 이야기 (0) | 2022.11.30 |