오류 메시지, 논리적인 사고
그리고 브라우저 개발자 도구 이외에
몇 가지 오류를 찾고 고치는 데 도움을 줄 수 있는
리액트 기능이 있습니다
이 기능을 시연하기 위해
Results.jsx 파일을 수정하여
이 results 배열을
컴포넌트 함수에서 꺼내 import 밑에 넣어
이 변화가 포함된 Results.jsx 파일을
첨부했습니다
이 부분을 수정한 이유는
이 상태로 새로고침했을 때, 모든 것이 작동하는 것처럼 보이기 때문입니다
이곳을 수정하면
테이블이 점점 길어지기만 한다는 것을 확인할 수 있는데
무언가 잘못되었음을 느낄 수 있습니다
이제 브라우저 콘솔에서
여러 개의 오류 메시지가 뜬다는 것을 확인할 수 있습니다
알림을 살펴보면, 모든 오류들은
두 children이 같은 키를 가지는 것에 대한 것입니다
이들은 여기에 있는 목록과 연관이 있어 보이는데
그 이유는 해당 리스트 내부에서 key 속성을 가진 요소들을
출력하고 있기 때문입니다
여기서 꽤 명백하게 보이는 문제점은
목록이 입력 값이 수정됨에 따라
삭제되고 대체되는 것이 아니라
계속 길어지는 것입니다
이제 다시 디버거를 사용해
코드에서 무엇이 문제인지 살펴볼 수 있습니다
하지만 그 전에 주목해야 할 것은
이 문제가 발생하는 건
여기 값들을 수정할 때만 일어난다는 점입니다
이 앱을 테스트할 때
해야하는 일들입니다
그럼에도, 에러는 즉각적으로 나타나는 에러가 아닙니다
적어도 이 에러는 앱이 시작될 때
리액트가 보여줄 수 있는 에러입니다
Strict Mode (엄격 모드)를 사용하면 할 수 있습니다
그래서 이 엄격모드를 사용해보겠습니다
그 후에 무엇이 이 에러를 발생하는지 설명드리겠습니다
엄격모드를 사용하는 건 특정하게 index.jsx에서 시작해야 합니다
하지만 원한다면 앱에 부분적으로만 활성화 시킬 수 있습니다
왜냐하면 엄격 모드는 결국 간단히 말해
리액트에서 import하는 컴포넌트이기 때문입니다
StrictMode라는 이름의 내장 컴포넌트입니다
그래서 StrictMode는 리액트가 제공하는 컴포넌트로써
여러분이 컴포넌트처럼 사용할 수 있습니다
더 정확히는 다른 컴포넌트들을
감싸는 컴포넌트입니다
예를 들어, 이 앱 컴포넌트에
이 앱 컴포넌트를 열림과 닫힘 태그를 사용한
StrictMode 컴포넌트로 감쌀 수 있습니다
애플리케이션 내 어디에서든 사용할 수 있다는 말이
이런 뜻이었습니다
루트 컴포넌트는 감싸지 않아도 됩니다
대신, StrictMode를 import하여
더 깊은 곳에서 사용할 수 있습니다
예를 들어 컴포넌트 트리 속에 중첩되어 말입니다
그리고 또 예를 들어, Results 컴포넌트만 감싸든지
UserInput 컴포넌트만 감싸든 원하는대로 할 수 있습니다
그리고 StrictMode로 루트 App 컴포넌트를 감싸는 건 흔한 일입니다
왜냐하면 StrictMode는 시스템 내부에서
앱 내 문제들을 잡아주는 일들을
몇 가지 하기 때문입니다
예를 들어, StrictMode 컴포넌트가 하는
가장 중요한 일은
모든 컴포넌트 함수를 두번씩 실행한다는 것입니다
한 번만 실행하지 않습니다
그리고 개발 단계에서만 그렇게 합니다
만약 어플리케이션을 배포 목적으로 준비 중이라
서버에 업로드 한다면
StrictMode는 더 이상 두번씩 컴포넌트들을 실행하지 않습니다
왜냐하면 그건 당연하게도 성능에 조금씩
영향을 주기 때문입니다
하지만 개발 단계에서는 그렇게 하는
이유는 컴포넌트들이 두 번씩 실행되면
에러를 발견하기가 더 쉽기 때문이고 지금처럼 재로딩하면
모든 컴포넌트들이 두 번씩 실행되면서
App 컴포넌트도 두 번 실행됩니다
그리고 여기 테이블도 두 번 출력되는데
뭔가 코드에 케이블을 증식시키는 문제가 있어 보입니다
물론 이게 문제를 고쳐주진 않습니다
그리고 무엇이 문제를 발생시키는지에 대해서도
알려주지 않습니다
하지만 즉각적으로 문제가 있다는 것을 알려줍니다
이 입력값을 수정하지 않아도
무언가 문제가 있다는 것이 보입니다
StrictMode가 활성화되어
전체 앱을 감싸준 덕분에
이 에러가 즉각적으로 보여진 것입니다
그리고 이 에러의 근원은
Results 컴포넌트에서 생기는 것인데
이 Results 배열을
컴포넌트 함수 바깥에서 생성하기 때문에 한 번만 생성되고
이 컴포넌트 함수가 리액트에 의해
상태가 바뀔 때마다
다시 실행될 때
그러니까 언제든 UserInput이 바뀔 때
파일의 다른 코드들
즉, 이 배열의 생성은 다시 실행되지 않으며
여전히 한 번만 실행됩니다
그래서 여기 무슨 일이 일어나는 것이냐면
배열이 생성되고
calculateInvestmentResults 함수 안에는
계속해서 아이템들이 추가되는데
동일한 메모리 내 배열에 추가됩니다
배열은 절대 초기화되거나 하지 않기 때문입니다
그래서 이 코드를 가지고
컴포넌트 함수로 돌아가서 새로운 배열이
이 컴포넌트 함수가 실행될 때마다 생성되도록 해야 합니다
그걸 가지고 이 앱을 재로딩하면
에러가 사라지고 콘솔에도 에러가 보이지 않습니다
그리고 이제 자신있게
이 값들을 수정해도 바뀌지 않는다고 말할 수 있습니다
StrictMode 덕분입니다