Final - "TypeError: Cannot read property 'blabla' of undefined" : Life Cycle of React

김진섭·2021년 6월 1일
0

Final

목록 보기
1/6

"TypeError: Cannot read property 'blabla' of undefined"

-환장하네-

리액트를 하면서 가장 싫고 환장하고 화나는 에러. 이번 프로젝트를 진행하면서 거의 30%는 이 에러를 잡느라 골머리 앓은 것 같다. 대체 이 놈의 근본적인 이유는 뭘까?

이번 글의 주인공. 사용 기술의 배열이 블렌더,파이널컷, 이런 식으로 붙어서 나왔었다. detailData.tools에 배열 형식이다. ,(따옴표)는 붙어서 나오니, 요소들 사이에 공백만 넣어주면 되겠지? 라고 생각했다. 그래서 처음 시도했던 방법은 js문법 .join().

이렇게 시도했었다. 결과는? "TypeError: Cannot read property 'join' of undefined". 이후로 무슨 수를 써도 undefined. detailData.tools가 undefined라는 얘기인데, return(render)은 분명 함수와 state들이 실행 된 후에 렌더링 될탠데 대체 왜? console.log로 찍어도 값이 분명히 나오는데 대체 왜?

스택오버플로우에서는 .join()이 리액트에서 먹히지 않는다는 글들이 보이길래 다른 방법을 찾아보았다. 그래서 찾은게 위의 맵과 .reduce를 사용한 방법인데, 복잡할 뿐더러 역시 "'map' of undefined"... 이쯤되자 방법이 문제가 아니라 근본적인 문제가 따로 있다는 생각이 들었다.

그래서,

1. 에러가 뜨는 이유

핵심 문제는 리액트의 라이프 사이클이었다.

에러가 발생하는 경우 다루고자 하는 값은 라이프 사이클의 첫번째 단계인 constructor에서 받아온 값이 아니라 재랜더된 값일 것이다.

이러한 재렌더가 일어나기 전 값(즉, 생겨나기 전)을 props로 넘겨 주거나, map과 같은 함수를 사용할때 주로 위와 같은 에러가 발생한다.

왜냐하면 재렌더가 일어나기 전의 비어있는 값(undefined)을 받아오기 때문이다.

이를 해결하기 위해서는?

1) 부모에게서 제대로 된 값이 넘어오는지 확인 할 것

2) 제대로 됐다면, 재렌더 된 값을 받아오도록 조건문을 줄 것

value && value.join(', ')

이런 식으로, 논리연산자를 통해 값이 존재하는가? 를 물어보고 존재하면 실행하라 라는 조건을 주면 된다. 조금 다른 방법으로는 .length가 0부터 큰가? 로 존재여부를 물어봐도 되겠다.

분명 회원정보 수정에서 한번 고초를 겪은 문제인대도 또 고통 받았다. 이번에는 또 고통 받지 않도록, 같은 문제에 헤매지 않도록 기록한다. 리액트를 사용한다면 라이프 사이클과 렌더링 과정에 대해 반드시 공부하고 숙지하자!

참조한 글: https://velog.io/@xedni/React-Life-cycle-%EB%9E%9C%EB%8D%94-%EC%88%9C%EC%84%9C

이전에는 이렇게, 전 페이지에서 바로 넘어오지 않는 값으로 재렌더링 여부를 결정했던 적이 있다. 부모 컴포넌트에서 값을 받아와야 하는데, 부모 렌더가 끝난 후 자식이 렌더 되는데 render-componentDidUpdate는 함께 묶여있으니 부모 컴포넌트가 업데이트 되기 전, 즉 재렌더 되기 전 값을 자식이 받아와서 자식 컴포넌트 업데이트를 통해 재렌더링을 하려하고 하니 값이 없이(undefined)로 날아오는 것. 이때도 단축평가논리계산법(?)을 통해 해결했다.

profile
성배를 지키는 토끼

0개의 댓글