React가 동작을 했다가~ 안 했다가

JINBOK LEE·2022년 7월 20일
0

React로 프로젝트를 만들 던 중, React가 동작을 했다가 안 했다가 하는 상황이 발생했다.

해당 이슈로 인해, 잘 작업을 하던 중 이따금씩 save를 할 때 마다 오류가 터져나와
지금 진행하던 부분이 잘 못 된건지, 이전에 발생한 오류가 또 발생한 것 인지 확인하며
시간을 허비하는 상황이 발생했다.

무언가 잘못해서 처음부터 동작을 안하면 안했지, 왜 동작을 했다 안했다 하는 걸까


import React, { useEffect } from "react";
import { movieAction } from "../redux/actions/movieAction";
import { useDispatch, useSelector } from "react-redux";
import Banner from "../components/Banner";
import MovieSlide from "../compimport ClipLoader from "react-spinners/ClipLoader";

const Home = () => {
  const dispatch = useDispatch();
  const { popularMovies, topRatedMovies, upcomingMovies } = useSelector(
    (state) => state.movie
  );
  console.log("home", popularMovies);
  console.log("home", topRatedMovies);
  console.log("home", upcomingMovies);

  useEffect(() => {
    dispatch(movieAction.getMovies());
  }, []);

  return (
    <div>
    
      {popularMovies.results && <Banner movie={popularMovies.results[0]} />}

      <h1>popularMovies</h1>
      <MovieSlide movies={popularMovies} />
      <h1>topRatedMovies</h1>
      <MovieSlide movies={topRatedMovies} />
      <h1>upcomingMovies</h1>
      <MovieSlide movies={upcomingMovies} />
    </div>
  );
};

export default Home;

위와 같이 Homepage를 구성하던 중,

{popularMovies.results && <Banner movie={popularMovies.results[0]} />}

해당 줄의 코드에서, AND (&&) 연산자를 사용하여 조건부 렌더링을 하는 단계에서
아래와 사진과 같은 오류가 발생하였다.


오류 내용

개발자 도구로 확인


react-redux의 useSelectior hook을 사용하여 구조분해할당 한 각 객체들에 (popularMovies,topRatedMovies,upcomingMovies) 데이터가 도착하지 않고 있는 것 같다.

Redux Devtool로 확인


해당 객체들에 데이터가 들어오고 있지 않음을 확인하였다.


이상한 점

코드를 수정하려 아무리 찾아보아도, 어디서 문제가 발생하는지 알 수가 없었다.
그러던 중, 오류가 발생한 해당 코드 줄을 삭제하고 저장한 뒤
다시 동일한 코드를 삽입하여 저장하였더니 정상적으로 동작함을 확인하였다.


정상적으로 API를 호출하여, 본래 구하고자 하던 정보를 받아온 모습

그렇다면 "코드의 문법은 올바르게 작성 하였으나, API 통신 과정에서 무언가 문제가 생겼던 것은 아닐까"
라는 생각으로 API 호출 관련 파일들을 다시금 확인하였다.

import api from "../api";

const API_KEY = process.env.REACT_APP_API_KEY;

function getMovies() {
  return async (dispatch) => {
    const popularMovieApi = api.get(
      `/movie/popular?api_key=${API_KEY}&language=en-US&page=1`
    );

    const topRatedApi = api.get(
      `/movie/top_rated?api_key=${API_KEY}&language=en-US&page=1`
    );

    const upcomingApi = api.get(
      `/movie/upcoming?api_key=${API_KEY}&language=en-US&page=1`
    );

    let [popularMovies, topRatedMovies, upcomingMovies] = await Promise.all([
      popularMovieApi,
      topRatedApi,
      upcomingApi,
    ]);

    console.log("promise all 이후의 popularMovies 데이터는?", popularMovies);
    console.log("promise all 이후의 topRatedMovies 데이터는?", topRatedMovies);
    console.log("promise all 이후의 upcomingMovies 데이터는?", upcomingMovies);

    dispatch({
      type: "GET_MOVIES_SUCCESS",
      payload: {
        popularMovies: popularMovies.data,
        topRatedMovies: topRatedMovies.data,
        upcomingMovies: upcomingMovies.data,
      },
    });
  };
}

export const movieAction = {
  getMovies,
};

위 api.js 파일에서 dispatch의 인자 중, payload의 각 객체값에 이미 .data 값을 넣은 값으로 할당을 해 주었는데 (ex. popularMovies: popularMovies.data) 그것에 또 .data를 하여 문제가 발생하던 것 이었다? (착각하였던 것)


해결

{popularMovies.results && <Banner movie={popularMovies.results[0]} />}

문제가 발생한 위 코드에서

{popularMovies && <Banner movie={popularMovies.results[0]} />}

위 코드처럼 수정을 하였더니 정상 작동하는 것을 알 수 있었다.
그렇지만 조건부 렌더링을 위하여, popularMovies의 result 값이 있으면
배너를 렌더하도록 하고자 했던 것이고, 아래 사진과 같이 results 값들은 잘 들어 왔던 것을 확인 하였었는데
왜 이러한 문제가 발생했었는지 모르겠다.

예상컨데,
React가 동작이 되다 안되다 하던 것은,
(정확히는 문제되는 코드를 지운 뒤, 저장을 하고, 다시 코드를 살린 뒤, 저장을 했을 때 작동하였다)

  1. 문제가 되는 코드라인을 지워 API호출에 성공하였다
  2. API호출이 성공된 채로, 다시 문제가 되었던 코드라인을 살린 것이었다
  3. 코드라인의 문법에 오류가 있었으나, 성공적으로 받아왔던 API호출 데이터를
    조건부 렌더링 절에서 인식하여 화면에 렌더링 하였다

아직 React 관련 지식이 부족하여, 무엇 하나 실수했을 때 그것의 원인을 찾고 해결하는데 많은 시간이 걸린다.
이번에 겪은 문제 또한 결국 자잘한 SyntaxError 였으며, 해당 코드가 어떻게 잠시나마 동작할 수 있었는지는
정확히 설명을 못하겠는 것이 사실이다.

이러한 점들이 너무나 답답하여 React 관련 서적을 읽고 React의 구조에 대해 더욱 깊이 공부하고 있는데
추후 해당 코드가 작동할 수 있었던 경로를 알게 된다면 이 글을 다시 한번 수정 할 예정이다.


시도 1

loading spinner를 적용하여, 이것이 popularMoves를 banner에 렌더하기 전 1차 가드의 역할을 하게끔하고, 이후 조건부 렌더링이 불필요할 것으로 예상하고 조건부 렌더링 절을 지우고

<Banner movie={popularMovies.results[0]} />

위와 같이 바로 컴포넌트를 불러왔는데, 처음 발생했던 오류와 똑같은 오류가 발생했다.
무엇이 문제일까..


시도2 (해결.. 타이핑 오류였다)

다음 날 코드를 다시 훑어보며, syntax error를 일으켰을 코드 한줄을 발견하였다.

function movieReducer(state = {initialState}, action)

생각 없이, reducer의 state 인자에 initialState를 전달하는데 있어서 그것을 대괄호로 감싸버린 것이다.

function movieReducer(state = initialState, action)

따라서 위와 같이 코드를 수정하여 이제는 잘 되는가 싶었는데..

또 다른 에러가 발생했었다.


좌측의 이미지처럼 redux devtool로 확인하면 분명 API호출은 잘 되었으나,
우측의 이미지처럼 console창에서 확인하면 upcomingMovies에 해당하는 results 값들이
undefined로 되어버리는 문제가 있음을 발견하였다.

해당 부분에서 문제가 생겨 지속적인 오류가 발생하는 것이라고 판단하였고,
upcomingMovies에 관한 코드들을 모두 훑어보기 시작했다.

어이없게도, movies를 moviee로 타이핑을 잘못하여 문제가 발생하였음을 드디어 알게 되었다.
이런 경우를 방지하기 위해서 오탈자를 감지하는 extension도 설치 했었음에도 불구하고,
너무나 기초적인 실수를 해 버렸었다.

moviee로 타이핑을 잘못했던 것은 이전에 확인하여 고쳤었고, 세이브가 되었다고 생각했었는데
세이브가 안되었던가 혹은 git pull 과정중에 문제가 있었던 것 같다.

사소한 실수로 인해 몇시간을 허비한 것 같다.
해결은 해서 다행이라는 생각이 들지만, 앞으로 이런 실수로 인해
아까운 시간을 날려먹는 일이 없도록 주의해야겠다!

profile
깔끔한 비즈니스 로직 설계를 위해 공부하는 FE 개발자

0개의 댓글