
개발을 하면서 잘못된 코드가 야기하는 오류를 찾으면서 수정할 수 있어야 한다.
아래 코드를 실행해보면 에러가 나온다.
App.js
const App = () => {
return (
<section id="goal-form">
<CourseInput onAddGoal={addGoalHandler} />
</section>
<section id="goals">
{content}
</section>
);
};
Line 42:6: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (42:6)
리액트의 리턴값은 하나의 태그로 감싸서 출력 해야한다. 그러므로 오류발생!
루트태그로 div를 이용하여 감싸서 해결한다.
App.js
const App = () => {
return (
<div>
<section id="goal-form">
<CourseInput onAddGoal={addGoalHandler} />
</section>
<section id="goals">
{content}
</section>
</div>
);
};
아래 코드를 실행해보면 에러가 나온다.
App.js
const App = () => {
const addGoalHandler = enteredText => {
( ... )
};
return (
<div>
<section id="goal-form">
<CourseInput onAddGoal={addGoalsHandler} />
</section>
<section id="goals">
{content}
</section>
</div>
);
};
Line 41:33: 'addsGoalHandler' is not defined no-undef
정의는 "addGoalHandler"로 정의했지만 사용은 "addsGoalHandler‘인데,
정의되지 않은 함수를 사용하려 했기 떄문에 오류가 발생한다.
Line 41줄로 가서 오타를 확인하고 고쳐서 해결한다.
App.js
const App = () => {
const addGoalHandler = enteredText => {
( ... )
};
return (
<div>
<section id="goal-form">
<CourseInput onAddGoal={addGoalHandler} />
</section>
<section id="goals">
{content}
</section>
</div>
);
};
다음 사진은 “두번째 추가”칸을 클릭하여 삭제하려고 한다.
하지만.. “두번째 추가”가 삭제되지 않고 “첫 추가”가 삭제되었음을 볼 수 있다.
컴파일도 잘되어서 오류메시지도 발생하지 않는다. 어떻게 해결해야할까?
해결방법은 두가지다.
우리가 삭제라는 행동을 했을때 발생했던 트리거는 삭제라는것을 알 수 있다.
그러므로 코드를 짯던 부분중에 “삭제”와 관련 되어 있음은 틀림없으므로 관련된 코드를 확인한다.
고유키를 담당하는 id부분이 하드코딩으로 고정되어있음을 확인할 수 있었다.
const App = () => {
const addGoalHandler = enteredText => {
setCourseGoals(prevGoals => {
const updatedGoals = [...prevGoals];
updatedGoals.unshift({ text: enteredText, id: 'goad1' });
return updatedGoals;
});
};
이런식으로 직접 생각하면서 찾아가는 방식도 있겠으나 다른 방식도 있다.
브라우저에서 컴파일과정에서 에러는 발생하지 않고 실행이 될 수는 있지만,
잘못됐을거 같은 코드에 대해서 경고메시지는 출력 한다.
개발자 도구에서 콘솔창의 로깅메시지를 보며 경고 메시지를 확인해보자.
두개의 자식이 같은 키를 갖는다고 경고메시지를 출력해주며,
at CourseGoalList 컴포넌트에 에 관련되어 있음을 볼 수 있다.
찾아가서 관련된 부분을 수정하여 해결한다.
const App = () => {
const addGoalHandler = enteredText => {
setCourseGoals(prevGoals => {
const updatedGoals = [...prevGoals];
updatedGoals.unshift({ text: enteredText, id: Math.random().toString() }); return updatedGoals;
});
};
특정 소스코드에 대해 아무것도 모르는 백지상태이거나 감을 잡지 못할때 사용해 볼 수 있는 방법이다.
브라우저 -> F12 -> Sources -> 내 파일의 코드로 이동하여 중단점을 활용해 디버깅 해보자.
중단점을 설정하는 방법은 다음 사진과 같이 라인을 클릭하여 중단점을 만들면 된다.
( 파란색으로 칠해진 8번째 라인이 중단점이다. )
코드중에서 삭제 트리거가 문제 되는 부분일 것이므로 삭제 함수로 가서 중단점을 잡아보자.
중단점을 잡았으면 트리거가 되는 “두번째 블록”을 클릭하여 삭제하려고 해보자.
클릭후 아래 사진과 같이 파란색부분까지 중단점으로 왔음을 볼 수있다.
"Step into Next function call“ 을 클릭하여 onDelete 함수를 호출해보자.
해당 함수로 이동하였고, goalId의 변수등의 정보를 볼 수 있다.
"Step over next function call"을 클릭하여 해당 함수를 다시 호출해보자.
함수를 다시 호출하였으나 문제점을 발견한것 같다.
goalId가 바뀌지 않는것이다.
id를 할당하는 부분으로 가서 알맞게 수정해주자.
const App = () => {
const addGoalHandler = enteredText => {
setCourseGoals(prevGoals => {
const updatedGoals = [...prevGoals];
updatedGoals.unshift({ text: enteredText, id: Math.random().toString() });
return updatedGoals;
});
};
구글에 react devtools 검색하여 확장 프로그램을 설치한다.
이 확장 프로그램인 리액트 devtools는 여러 가지 시험을 해볼 수 있고 어떻게 모든 것들이 연결되어 있는지 이해하며 다양한 시나리오에서 여러 사용 사례를 테스트 해 볼수 있게한다. 리액트 앱을 분석하는데 아주 유용한 도구.
오른쪽 상단에 컴포넌트 탭을 이용하여 분석 해볼수 있다.