-
[JS, TS]TypeError: cannot read properties of undefined (reading 'length') (해결)(+3월 17일 수정)Java Script & Type Script/Trouble Shooting 2023. 2. 18. 18:02728x90
서버에서 보내주는 response값을 담은 schedule의 구조, invitees (일정참여자) 구조
-
- 다른 코드에 변화가 없음에도 될 때도 있습니다. 다만 새로고침을 하거나 여기에서 다른 코드가 추가되면 이 부분에서 에러가 발생합니다.에러메세지 (invitees의 length를 인식할 수 없는 문제.)
- invitees가 array형태인데, length를 가져올 수 없다는 것이 이해가 안감.
- 특히 이 부분이 항상 에러가 발생하는게 아니라, 불러오는데 성공할 때가 있고 에러가 생길 때도 있어서 더욱 의아함
- 다른 코드에 변화가 없음에도 될 때도 있습니다. 다만 새로고침을 하거나 여기에서 다른 코드가 추가되면 이 부분에서 에러가 발생합니다.에러메세지 (invitees의 length를 인식할 수 없는 문제.)
이 부분에서 에러가 생기는데,
이게 콘솔에도 찍히고
return에서도 화면에 잘 그려지다가 새로고침하거나 전혀 상관없는 코드가 추가되고나면 화면이 날아가면서 에러가 뜨니까 error tracking이 안되는 상황.
처음으로 컴퓨터가 멍청한건가 생각을 했다.
const ScheduleDetail = () => { // 모달 노출시키는 여부 const [modalOpen, setModalOpen] = useState(false); const showModalHandler = () => { setModalOpen(true); }; //id구하기 const { id } = useParams(); //데이터베이스를 담을 schedule변수. const [schedule, setSchedule] = useState([]); const fetchTodos = async () => { await axios .get(`서버URL/${id}`, { headers: { Authorization: localStorage.getItem("Authorization"), }, }) .then((appData) => { setSchedule(appData.data.data); }, []); }; const time = schedule.time?.split(":", 2).join(":") useEffect(() => { fetchTodos(); }, [id]); console.log(schedule); //문제의 코드 구간입니다.. length가 잘 불려올 때도 있고 에러가 발생할 때도 있습니다. const numberOfJoiner = schedule.invitees.length; console.log(numberOfJoiner); const joinerList = []; for (let i = 0; i < numberOfJoiner; i++) { joinerList.push( <div className="ml-[5px]">{schedule.invitees[i].username}</div> ); } return ( <div className="bg-[#EDF7FF] h-[734px] width-[375px]"> <TopNavBar /> <div> {modalOpen && <KebabModal setModalOpen={setModalOpen} />} {/* bg는 유저가 등록시에 선택한 cardColor로 */} <div className={`h-[250px] bg-${schedule.cardColor} pl-[18px] pt-[71px] pr-[21px] text-white`} > <div className="flex flex-row-reverse"> <img className="h-[20px] flex " src={kebab} alt="케밥메뉴" onClick={showModalHandler} /> </div> <div className="flex space-x-3 text-[18px] mt-[-18px] font-light "> <div>{schedule.date}</div> <div> {time}</div> </div> <div className="mt-[28px] font-semibold text-[24px]"> {schedule.subject} </div>{" "} <div className="place-content-end font-light flex text-[18px] mt-[70px]"> D- {schedule.dday === 0 ? <div>day</div> : <div>{schedule.dday}</div>} </div> </div> <div className="text-[#12396F]"> {/*여기부터 문제의 코드 구간입니다...*/} <div> {numberOfJoiner !== 1 ? ( <div className="mt-[30px] h-[98px] ml-[20px]"> 참여자 <div className="bg-[#CEE4F8] h-[50px] w-[335px] mt-[20px] p-[15px] shadow flex rounded-lg"> {joinerList} </div> </div> ) : ( <div /> )} </div> {/*문제의 코드 구간 끝입니다...*/} <div className="h-[234px] mt-[30px] mb-[8px] ml-[20px]"> 일정내용{" "} <div className="bg-[#CEE4F8] shadow h-[186px] w-[335px] mt-[20px] p-[15px] flex rounded-lg"> {schedule.content} </div> </div> </div>{" "} </div> {modalOpen ? false : <BottomNavi />} </div> ); }; export default memo(ScheduleDetail);
전체 코드.....
문제가 해결되면 수정 꼭 해야지....
문제 해결!!!
세상에 마상에 지난 주부터 골머리썩던 에러를 드디어 해결했다!!!
참고한 블로그..
https://devbirdfeet.tistory.com/47
React 실행오류 Cannot read property 'map' of undefined
Updated 2022/10/07 React hook 을 사용하여 네이버 뉴스 검색 API 를 데이터를 화면에 뿌려주려 하다가 이런 에러메시지가 나왔다. 문제상황) TypeError: Cannot read property 'map' of undefined 왜 나에게 이런일이...
devbirdfeet.tistory.com
감사합니다....
<div> {numberOfJoiner !== 1 ? ( <div className="mt-[30px] h-[98px] ml-[20px]"> 참여자 <div className="bg-[#CEE4F8] h-[50px] w-[335px] mt-[20px] p-[15px] shadow flex rounded-lg"> {joiner && joiner.map((a) => { return <span className="text-sm">{a.username}</span>; })} </div> </div> ) : ( false )} </div>
고쳐진 코드
삼항연산자 조건부 렌더링으로 Joiner가 1명이 아닐 때, 즉 나 혼자만의 일정이 아닐 땐 참여자리스트가 보여지고, 나 혼자만의 일정일 땐 false를 줘서 리스트가 아예 렌더링되지 않는다.
그리고 미친듯이 발생하던 length 에러도
const numberOfJoiner = joiner && joiner.length;
간단히 And 논리연산자로 고쳐졌다..
AND 연산자(&&)
And연산자는 a && b 에서 a와 b 둘다 true일 경우에만 식이 성립됩니다.
a와 b중 하나라도 false인 경우, null과 값이 아무것도 출력하지 않습니다.
그동안 length가 undefined가 뜨고, map을 read할 수 없다한 이유는?
React 는 렌더링이 화면에 커밋 된 후에야 모든 효과를 실행하기 때문이었다. 즉 React는 return에서 .map(...)을 반복실행할 때 첫 턴에 데이터가 아직 안들어와도 렌더링이 실행되며 당연히 그 데이터는 undefined로 정의되어 오류가 나는 것이다.
리액트 조건부렌더링 공식문서,,
https://ko.reactjs.org/docs/conditional-rendering.html
조건부 렌더링 – React
A JavaScript library for building user interfaces
ko.reactjs.org
+
3월 15일 최종발표때 이 트러블 슈팅을 발표했다.
이 부분의 스크립트는 다음과 같다
일정 상세보기 페이지에서 서버의 response데이터 중 invitees의 length를 구해 참여자가 0일 경우 조건부렌더링을 하는 부분이 있었는데, 서버에서 보내주는 해당 데이터가 배열의형태로 존재하지만 (cannot read properties of undefined라는) invitees가 undefined이기때문에 length를 구할 수 없다는 type error를 마주쳤습니다. 이 부분은 멘토님께 조언을 구했고, 서버의 response데이터가 렌더링시점에서 undefined로 인식되어서 에러가 발생한 것이라고 원인을 파악하였습니다. 이 문제을 해결하기 위해 Short Circuit Evaluation이라는 개념을 공부하였고, and연산자를 이용하여 피연산자가 undefined로 인식되어도 type error가 발생하지 않게해서 데이터를 불러오는 시간을 벌 수 있도록 설정하여 해결할 수 있었습니다.
그리고 이건 3월 17일 코딩애플 듣다가 발견한 내용. 나처럼 이런 에러 겪어서 당황하는 초보 개발자가 많나보다...
애플선생님이 하신 얘기처럼 state안에 뭐 들어있으면 보여달라고 if 문 추가해서 (나는 &&연산자로) 해결하는게 일반적인 방법인가보다.
728x90'Java Script & Type Script > Trouble Shooting' 카테고리의 다른 글
[JS] this 바인딩에대한 고찰... (항해 수료 후 근황, 스파르타 취업준비반) (0) 2023.04.03 38. 3월 16일 (0) 2023.03.16 34. react-datepicker 야무지게 잘 쓰는 법. Feat.datepicker 시차해결. datepicker한국시간표현 (0) 2023.03.04 30. Final Project [trouble shooting-3] - useState비동기문제 함수형 업데이트로 해결! chat GPT야 고마워 (0) 2023.02.23 27. Final project [Trouble Shooting -1]리액트 무한렌더링-불필요한 렌더링을 막는 리액트 훅 useCallback, useMemo (해결중) (0) 2023.02.16 -