TypeError: Cannot read properties of undefined (reading 'length') 에러는 typescript를 사용한다면 무조건 봤을 에러메세지이다.
원인이 무엇일까?
여러가지 이유가 있을 수 있지만 거의 대부분은 string이나 array의 길이 속성을 참조하기 때문에 발생하는 것이다. 예를 들어, string 인수를 사용하는 함수가 하나 있다고 해보자. 그 함수를 호출했을 때 해당 string 인수 값이 없다면 이 에러를 보게 될 것이다.
위 화면을 보면, zustand에서 magazineStore를 만들어 놓고 sorting이라는 값을 담아서 사용하고 있다. 하지만 RegionResult 컴포넌트를 사용하는 순간에는 magazineStore에서 sorting을 undefined로 인식한다. 따라서 아래의 방어 코드를 추가해서 문제를 해결했다.
기존 코드
(...)
const {sorting} = magazineStore();
(...)
방어적인 코드 추가
import { useInfiniteQuery } from "@tanstack/react-query";
import { getRegionResult } from "lib/react_query/getRegionResult";
import { useRouter } from "next/router";
import magazineStore from "store/magazineStore";
import writeStore from "store/writeStore";
const RegionResult = () => {
// 아래 tanstack-query에 파람즈로 sorting값을 넘겨줘야하는 상황
const { sorting } = magazineStore() || { sorting: "hot" };
(...)
const { data, fetchNextPage, hasNextPage, isFetching } = useInfiniteQuery({
queryKey: ["magazineList", "regionId", regionIdParam, sorting],
queryFn: getRegionResult,
initialPageParam: 0,
getNextPageParam: (lastPage, pages) => {
return lastPage.data.length === 0 ? undefined : pages.length;
},
staleTime: 60 * 1000,
gcTime: 300 * 1000,
});
return { data, fetchNextPage, hasNextPage, isFetching };
};
export default RegionResult;
원래 sorting의 default 값이 "hot"이므로 magazineStore에서 값을 받아오지 못하는 경우 "hot"이 sorting에 담기도록 했다.
해결방안이 뭘까?
1. 왜 그 object가 undefined인지 이해해야 한다.
- 특정 형태를 갖는 네트워크 응답에 의존하고 있나?
- 사용자 입력을 처리하고 있나?
- 외부 함수이거나 라이브러리가 호출되고 있나?
- 아니면 단순히 로직 이슈인가?
2. 방어적인 타입 확인 코드를 추가하자. (add defensive type checking)
api 응답의 변경, 함수 업데이트, 사용자의 예측 불가능한 행동에 대비해서 타입 확인을 방어적으로 해줘야한다. 예를 들어, api fetching 코드에는 아래처럼 defensive type checking을 할 수 있다.
fetch("https://example.com/api")
.then(resp => {
return resp.json();
})
.then(json => {
if (!json || typeof json.foo != 'string') {
// joson이 반환되지 않았거나, 타입이 string이 아닌 경우에...
// Record an error, the payload is not the expected shape.
}
});
3. 확실히 이슈가 해결되었는지 체크하자.
"Just because your application works today, doesn’t mean an error won’t be discovered tomorrow." 명언이다...
[참고] https://trackjs.com/blog/debugging-cannot-read-property-length-of-undefined/
'TypeScript' 카테고리의 다른 글
TypeScript, Next.js, React.js 이미지 미리보기 | Image Preview (0) | 2024.03.18 |
---|---|
제네릭 | 한 입 크기로 잘라먹는 타입스크립트 (1) | 2024.03.12 |
서로소 유니온 타입 | 한 입 크기로 잘라먹는 타입스크립트 (0) | 2024.03.03 |
타입단언 (value as typeName) | 한 입 크기로 잘라먹는 타입스크립트 (0) | 2024.03.03 |