Chap8. 리액트 앱 디버깅

Muru·2023년 11월 6일

[React] 지식 저장소

목록 보기
15/30
post-thumbnail

8.1 : Chap8에선 무엇을 배우는가?

개발을 하면서 잘못된 코드가 야기하는 오류를 찾으면서 수정할 수 있어야 한다.

  1. 특정 상황에서의 리액트 오류 메시지를 이해한다.
  2. 앱이 실행 되는동안 코드를 이해한다.
  3. 브라우저에 확장 설치가 가능한 리액트 개발 도구를 살펴본다.



8.2 : 다양한 오류 메시지들 해결하기

8.2.1 : Parsing error: Adjacent JSX elements must be wrapped

아래 코드를 실행해보면 에러가 나온다.
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>
  );
};

8.2.2 : ‘ ‘ is not defined no-undef

아래 코드를 실행해보면 에러가 나온다.
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>
  );
};



8.3 : 코드 흐름 및 경고 분석

다음 사진은 “두번째 추가”칸을 클릭하여 삭제하려고 한다.

하지만.. “두번째 추가”가 삭제되지 않고 “첫 추가”가 삭제되었음을 볼 수 있다.

컴파일도 잘되어서 오류메시지도 발생하지 않는다. 어떻게 해결해야할까?
해결방법은 두가지다.

  1. 해당 로직에 찾아가서 해결하기.
  2. 개발자 도구에서 콘솔창의 로깅메시지를 보며 경고 메시지를 확인한다.

8.3.1 : 해당 로직에 찾아가서 해결하자.

우리가 삭제라는 행동을 했을때 발생했던 트리거는 삭제라는것을 알 수 있다.
그러므로 코드를 짯던 부분중에 “삭제”와 관련 되어 있음은 틀림없으므로 관련된 코드를 확인한다.

고유키를 담당하는 id부분이 하드코딩으로 고정되어있음을 확인할 수 있었다.

const App = () => {
  const addGoalHandler = enteredText => {
   setCourseGoals(prevGoals => {
    const updatedGoals = [...prevGoals];
    updatedGoals.unshift({ text: enteredText, id: 'goad1' });
    return updatedGoals;
   });
  };

이런식으로 직접 생각하면서 찾아가는 방식도 있겠으나 다른 방식도 있다.

8.3.2 : 개발자 도구의 콘솔창을 활용하자.

브라우저에서 컴파일과정에서 에러는 발생하지 않고 실행이 될 수는 있지만,
잘못됐을거 같은 코드에 대해서 경고메시지는 출력 한다.
개발자 도구에서 콘솔창의 로깅메시지를 보며 경고 메시지를 확인해보자.

두개의 자식이 같은 키를 갖는다고 경고메시지를 출력해주며,
at CourseGoalList 컴포넌트에 에 관련되어 있음을 볼 수 있다.
찾아가서 관련된 부분을 수정하여 해결한다.

const App = () => {
  const addGoalHandler = enteredText => {
   setCourseGoals(prevGoals => {
    const updatedGoals = [...prevGoals];
  updatedGoals.unshift({ text: enteredText, id: Math.random().toString() });    return updatedGoals;
   });
  };



8.4 : 중단점(breakpoing) 작업하기

특정 소스코드에 대해 아무것도 모르는 백지상태이거나 감을 잡지 못할때 사용해 볼 수 있는 방법이다.

브라우저 -> 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;
   });
  };



8.5 : 리액트 DevTools 사용하기

구글에 react devtools 검색하여 확장 프로그램을 설치한다.
이 확장 프로그램인 리액트 devtools는 여러 가지 시험을 해볼 수 있고 어떻게 모든 것들이 연결되어 있는지 이해하며 다양한 시나리오에서 여러 사용 사례를 테스트 해 볼수 있게한다. 리액트 앱을 분석하는데 아주 유용한 도구.

오른쪽 상단에 컴포넌트 탭을 이용하여 분석 해볼수 있다.

profile
Developer

0개의 댓글