오류 예제 코드
https://codesandbox.io/p/sandbox/debugging-start-vy38s8?file=%2Fsrc%2Findex.js%3A7%2C1
리액트 디버깅하기
위와 같은 코드에서 아래와 같은 오류가 생겼다면 다음과 같이 해석할 수 있다.
valueEndOfYear이 정의 되지 않았다.
따라서 그 값부터 확인해보자
또한 아래 메세지들은 스택 트레이스로 이 오류로 인해 이어지는 코드의 목록이다.
따라서 다음과 같이 해결할 수 있다.
-> caculatorInvestmentResults 함수를 보면 duatrion이 0일때 빈 배열이 된다.
->빈 배열일때 valueEndOfYear이 정의되지 않는다.
->따라서 배열 길이가 0일때 예외처리를 해준다.
import { calculateInvestmentResults, formatter } from "../util/investment.js";
export default function Results({ input }) {
const results = [];
calculateInvestmentResults(input, results);
//배열의 길이가 0이면 예외처리를 해준다
//이렇게 하면 빈배열일때 정의 되지 않은 valueEndOfYear오류를해결할 수 있다
if (results.length === 0) {
return <p>invalid data</p>;
}
const initialInvestment =
results[0].valueEndOfYear -
results[0].interest -
results[0].annualInvestment;
return (
<table id="result">
<thead>
<tr>
<th>Year</th>
<th>Investment Value</th>
<th>Interest (Year)</th>
<th>Total Interest</th>
<th>Invested Capital</th>
</tr>
</thead>
<tbody>
{results.map((yearData) => {
const totalInterest =
yearData.valueEndOfYear -
yearData.annualInvestment * yearData.year -
initialInvestment;
const totalAmountInvested = yearData.valueEndOfYear - totalInterest;
return (
<tr key={yearData.year}>
<td>{yearData.year}</td>
<td>{formatter.format(yearData.valueEndOfYear)}</td>
<td>{formatter.format(yearData.interest)}</td>
<td>{formatter.format(totalInterest)}</td>
<td>{formatter.format(totalAmountInvested)}</td>
</tr>
);
})}
</tbody>
</table>
);
}
이때는 오류 메세지가 뜨지 않아 확인하기 어려운 오류이다.
따라서 디버깅을 통해 해결할 수 있다.
디버깅은 F12를 눌러 소스에서 페이지에 들어가 내 작업폴더로 들어간뒤 디버깅 원하는 라인을 누르면 된다.
-> 처음에는 정상작동을 하므로 caculator함수에는 문제가 없다.
-> 값을 변경하는 부분이 문제인 것 같으므로 그 부분을 확인한다.
위에 newValue를 보면 문자열이 들어간 것을 볼 수 있다. 바로 이 부분이 문제였던 것이다!
import { useState } from 'react';
import Header from './components/Header.jsx';
import UserInput from './components/UserInput.jsx';
import Results from './components/Results.jsx';
function MainCaculator() {
const [userInput, setUserInput] = useState({
initialInvestment: 10000,
annualInvestment: 1200,
expectedReturn: 6,
duration: 10,
});
function handleChange(inputIdentifier, newValue) {
setUserInput((prevUserInput) => {
return({
...prevUserInput,
[inputIdentifier]: +newValue, //+만 붙여주면 된다
})
});
}
return (
<>
<Header />
<UserInput userInput={userInput} onChange={handleChange} />
<Results input={userInput} />
</>
);
}
export default MainCaculator;
React Strict Mode
리액트에서는 strict mode라는 것이 있다.
대표적인 기능으로는 모든 컴포넌트 함수를 두번씩 실행시켜 준다.
개발 단계에서만 그렇게 하므로 서버에 업로드할 경우는 신경쓰지 않아도 된다.
->이렇게 두번씩 실행시켜줌으로써 오류를 발견하게 도와준다.
results함수를 밖으로 뺴내어 생긴 오류 코드
import { calculateInvestmentResults, formatter } from "../util/investment.js";
//이렇게 하면 배열이 초기화 되지 않고 계속해서 요소들이 담기게 된다.
//따라서 오류가 발생한다.
const results = [];
export default function Results({ input }) {
calculateInvestmentResults(input, results);
if (results.length === 0) {
return <p>invalid data</p>;
}
const initialInvestment =
results[0].valueEndOfYear -
results[0].interest -
results[0].annualInvestment;
return (
<table id="result">
<thead>
<tr>
<th>Year</th>
<th>Investment Value</th>
<th>Interest (Year)</th>
<th>Total Interest</th>
<th>Invested Capital</th>
</tr>
</thead>
<tbody>
{results.map((yearData) => {
const totalInterest =
yearData.valueEndOfYear -
yearData.annualInvestment * yearData.year -
initialInvestment;
const totalAmountInvested = yearData.valueEndOfYear - totalInterest;
return (
<tr key={yearData.year}>
<td>{yearData.year}</td>
<td>{formatter.format(yearData.valueEndOfYear)}</td>
<td>{formatter.format(yearData.interest)}</td>
<td>{formatter.format(totalInterest)}</td>
<td>{formatter.format(totalAmountInvested)}</td>
</tr>
);
})}
</tbody>
</table>
);
}
참고
https://www.udemy.com/course/best-react/?couponCode=KEEPLEARNING
'코딩 정보 > React' 카테고리의 다른 글
[React] context api를 이용해서 props drilling 막기 (0) | 2024.07.14 |
---|---|
[React] useRef의 응용과 createPortal 에 대해 알아보자 (1) | 2024.07.04 |
[React] css에 대해 알아보자 [styled component] (0) | 2024.06.30 |
[React] css에 대해 알아보자 [바닐라 css] (0) | 2024.06.29 |
[React] 틱택토 게임을 통해 개념 다지기 (0) | 2024.06.28 |