저번 강의에서 다룬 프로젝트가
지금 제 브라우저에서 실행되고 있습니다
그냥 봤을 때는 전혀 문제가 없어 보입니다
브라우저 개발자 도구를 열게 되면
콘솔에 오류는 없고
실수로 혹은 의도적으로 0이나
음수의 값을 duration(기간)에 대입하기 전까지는 모든 것이 잘 작동하는 것처럼 보입니다
이 시점에서, 모든 것이 멈추고
여러분께 빈 화면만이 남았을 것입니다
그리고 개발자 도구를 열면
오류 메시지가 여러분을 반깁니다
물론, 여러분이
필수 연습 강의를 수강했다면
그 부분에서 똑같이 발생하고 해결했던 오류이긴 합니다
하지만 그 강좌에서는 제가
여러분께 문제와 해결책만 알려드리고
오류 메시지의 이유를 찾는 방법을
설명해 드리지 않았습니다
따라서 그것이, 지금 할 내용입니다
왜냐하면 이것처럼 오류와 오류 메시지를 마주하게 되면
여러분은 쉽게 패닉할 수 있습니다
많은 양의 글자와
많은 빨간색이 화면에 있기 때문입니다
하지만 여러분이 패닉하지 마셔야 하는 이유는
대부분의 리액트 오류 메시지들은
꽤나 도움이 되고 통찰력 있기 때문입니다
그리고 이 모든 것들은
빨간색으로 표시된 글자의
상대적으로 앞쪽에 등장하는 메인 메시지로 시작됩니다
우리는 이것이 Uncaught TypeError (정의되지 않은 타입의 에러)라는 것을 알 수 있는데
그것은 크게 도움이 되지 않을지도 모릅니다
그러나 마지막에 이 코드를
실행하려 하는 브라우저가
정의되지 않은 값의 속성들을 읽어 들이는 데
실패했다는 것을 알 수 있습니다
정확하게 말하자면
이것이 valueEndOfYear 속성을 읽는 데 실패했습니다
이것이 접근하려고 하는 객체가
정의되지 않은 것 같았기에
이 속성과 그 안에 저장되어 있던 값에 접근하는 데에
실패했습니다
그것이 마지막에 있는 오류 메시지가 알려주는 바입니다
그리고 이것은 오류의 원인을
코드의 어느 부분부터 찾아봐야 할지
좋은 아이디어를 줍니다
우리는 당연히
valueEndOfYear 속성에 접근하는 부분에서 시작해야 합니다
그리고 이 앱과 기초 코드에서
그것은 Results JSX 파일 안에 들어 있습니다
그리고 예를 들어 코드의 이 줄이
우리가 이 속성에 접근하려고 하는 부분입니다
하지만 여러분은 이 속성의
사용을 직접 확인할 필요가 없습니다
대신, 이 오류 메시지의 실제 메시지 뒤에
여러분은 단순히 이 오류 메시지 밑의 출력인
stack-trace를 얻었습니다
이것은 단순히 이 오류로 이어지는
코드의 실행 목록입니다
예를 들어 이곳을 보시면
오류가 Results 함수에서 오고 있다는 것을 알 수 있습니다
그래서 여기 Results 컴포넌트 함수를 보시면
그곳에서 8행이라는 뜻입니다
그리고 16은 열을 의미하는데
16번째 글자로 이해할 수 있습니다
하지만 주로 중요한 것은 행의 번호입니다
그리고 이것이
이 results 함수로 돌아가서
8행을 들여다볼 수 있도록 합니다
그리고 그것은, 제가 방금 찾아낸 그 행과 같습니다
하지만 우린 그 속성을 찾아봐야 할 필요도 없습니다
왜냐하면 여기 이 흔적을 따라가고
바로 파일과 번호로 갈 수 있기 때문입니다
그럼 이제 오류가
이 줄의 코드에서 발생한다는 것을 알았습니다
자, 이 줄의 코드는 맞습니다
하지만 돌아가 보시면, 오류 메시지에서는
undefined라는 값에서 이 속성을 읽는 데 실패한 것이
문제라고 합니다
그래서 이 줄의 코드에 실제 문제는
이 년도가 정의되지 않은 점입니다
results[0]가 정의되지 않은 값을 가지고 있는 것 같습니다
그러므로 당연하게도
results들이 모여있는 곳으로 가야 합니다
연습 강좌 부분과는 다르게
이곳의 코드를 살짝 바꿨고
results 배열은 이제 여기에서 생성되는 배열이며
calculateInvestmentResults에
인자로 전달되는 것입니다
그리고 그 함수에서
이것이 입력값으로 받아 들여져
이 함수 안에서 조작되는 것입니다
추후 강의에서 results를 다루는 방식을
왜 이렇게 바꿨는지에 대한 주제로 돌아오겠습니다
하지만 여기서 중요한 것은
이 results 배열이 초기에는 비어있다는 것입니다
그 말은 즉, 당연하게도
해당 배열의 첫 번째 요소에 접근하려는 것은 실패할 것을 의미합니다
결국 문제는
이 calculateInvestmentResults 함수 내에서
results 배열이 덧붙여지지 않는다는 것입니다
자 이 함수로 오면
이론적으로 이 results 배열이
새 요소를 받는다는 것을 확인할 수 있습니다
하지만 그것은 이 for 반복문 안에서만 일어나는 일입니다
문제는
첫 번째 요소가 정의되지 않아
첫 요소가 없는 것이기 때문에
이 for 반복문이 절대 실행되지 않는 것이
문제입니다
그러므로, 이 for 반복문이
어떻게 구성되어 있는지 확인해 봅시다
그리고 마지막 부분에서
i가 duration보다 작은 동안 반복하는 것을 확인할 수 있습니다
만약 이 코드가 실행되지 않는다면
가능한 유일한 경우는
duration이 i보다 작은 경우
(i보다 크지 않은 경우)
일 때 입니다
아마 이것이 i 보다 작아 보입니다
그리고 당연하게도 이런 경우는 앱에서
duration에 0이나 -1
혹은 이와 같은 값을 입력했을 때의 경우입니다
이제 여러분은 문제의 범위를 좁혀
문제가 무엇인지 이해했습니다
이 코드가 duration에 음수의 값이 입력되어
실행되지 않는다면
여기에 있는 이 코드가 첫 요소가 없기 때문에 실패한다는 것이 문제라는 것을 말입니다
그러므로, 이 문제를 해결하기 위해
여기에 if 조건문을 추가하여
results의 길이가 0인지 확인하여
요소가 없는지 확인합니다
그리고 그 경우에 예를 들어
'Invalid input data (유효하지 않은 입력값입니다)'라는 문구나
비슷한 것을 반환할 수 있을 것입니다
여기서 반환하는 것이기 때문에
이후의 코드는 실행되지 않습니다
이것이 자바스크립트가 작동하는 방식입니다
그러므로 일종의 안전장치로 활용하는
이 if 조건문을 사용하면
첫 요소가 없을 때
이 코드가 실행되지 않도록 할 수 있습니다
그리고 그 대신 이 오류 메시지를 보여줄 수 있습니다
그리고 단순히 서식을 위해
이 문구를 중심에 맞춰 주겠습니다
하지만 그렇게 할 경우
저장한 후 다시 실행하고 duration에 0이나 -1을 입력하면
더 이상 앱이 멈추지도 않고
콘솔에서 오류 메시지도 뜨지 않는다는 것을 알 수 있습니다
그 대신, 화면에서 이러한 출력을 얻게 됩니다
그리고 이것은
앱이 멈추지 않으면서
웹사이트 사용자에게 무엇이 잘못되었는지 알려줄 수 있는
앱을 만드는 방법일 것입니다
여기에 이 코드를 추가할 수 있었던 이유는
오류 메시지를 읽고
이해하고
이 오류의 원인을 찾을 수 있었기 때문입니다