HTML, CSS, JS만을 활용한 영화 검색 페이지 구현 + 반성문

    반응형

    반성문

     

    독학으로 여러 강의들을 들으며 공부를 할 때 클론 코딩으로 쉽게 만들었던 영화 검색 페이지를 클론 코딩이 아닌 아는 지식을 활용해서 구현하는 과제를 받았다. 클론 코딩으로 공부하면서 당연히 다 완벽하게 할 줄 아는구나라고 생각했는데 이번 과제를 구현하면서 정말 수박 겉 핥기 식으로 공부했다는 걸 다시 한번 뼈저리게 느꼈다.

     

    우선 각각의 역할을 분리하고 분명히 하라는 조건을 받았다. 모듈화를 통해서 코드의 재사용 성과 유지 보수성을 높이기 위해서 나름의 구조를 아래와 같이 분리했다.

     

    구조

     

    SPA를 만들어봐야 하나 MPA를 만들어야 하나 많은 고민을 하다가 여태까지 해왔던 기초적인 부분들을 다시 한번 다지고 따라간다는 마음으로 MPA를 만들었다. styles 디렉토리에 각 구역별로 css 파일을 분리하고 font, reset을 따로 두어 index에서 import 하는 방식으로 사용했다.

     

    js 디렉터리도 API의 사용과 UI를 업데이트하는 부분을 따로 나누었다. 중요했던 API_KEY의 경우에는 react를 사용했을 때는.env로 간편하게 해결했지만 이곳에서는 api.js를 따로 만들고. gitignore에 추가해서 올리지 않는 방법으로 키를 숨겼다.

     

    1일차의 미션은 성공적으로 데이터 가져오기였고 기존에 미리 TMDB에 가입하고 API 키를 발급받아 놓은 상태라 수월했다.

    import TMDB_API_KEY from "./apiKey.js";
    
    export const getRatedMovies = async (page) => {
      const url = `https://api.themoviedb.org/3/movie/top_rated?page=${page}&language=ko`;
    
      try {
        const response = await fetch(url, {
          headers: {
            accept: "application/json",
            Authorization: `Bearer ${TMDB_API_KEY}`,
          },
        });
    
        const data = await response.json();
    
        return {
          results: data.results,
          totalPage: data.totalPage,
          currentPage: data.page,
        };
      } catch (error) {
        throw new Error(`이런 ${error} 가 발생했어요!`);
      }
    };

     

    react에서 공부했던 무한 스크롤도 추가로 구현하기 위해서 page를 받아서 계속 업데이트하고 실행해 주려고 했다. 성공적으로 데이터가 출력되고 아무런 에러 없이 UI 구현까지 마쳤다.

    // 문자열 길이 조절
    const strCut = (str, cutNum) => {
      if (str.length > cutNum) return str.substring(0, cutNum) + "....";
    
      return str;
    };
    
    // 영화 카드 UI 그리기
    export const displayMovieCard = async (page, plusElement) => {
      const moviesData = await getRatedMovies(page);
    
      if (moviesData && moviesData.results.length > 0) {
        try {
          moviesData.results.forEach((movie) => {
            const divEl = document.createElement("div");
            divEl.setAttribute("key", movie.id);
            divEl.classList.add("movie__card");
            const movieItem = `
                <img class="movie__img" src="https://image.tmdb.org/t/p/w300${
                  movie.poster_path
                }" alt="${movie.title}"/>
                <h3 class="movie__title">${strCut(movie.title, 20)}</h3>
                <p class="movie__desc">${
                  movie.overview ? strCut(movie.overview, 35) : "설명이 없습니다."
                }</p>
            `;
    
            divEl.innerHTML = movieItem;
            plusElement.append(divEl);
          });
        } catch (error) {
          throw new Error(`이런 ${error} 가 발생했습니다.`);
        }
      }
    };

     

    출력되는 영화 데이터의 설명 부분이 너무 길어 UI가 변경되는 문제가 있어서 문자열이 일정 길이보다 길면 잘라서 생략하는 함수를 만들고 일정한 간격을 가진 UI를 만들었다.

     

    첫째 날은 이렇게 끝을 내었다. react를 할 줄 안다고, next를 사용해 봤다고 너무 건방져 저 있던 것 같다. 우물 안 개구리가 따로 없어서 구현하는 내내 혼자 스스로에게 화를 내었다. 정말 속상했지만 아직 늦지 않았다고 생각한다. 다시 기초부터 탄탄히 쌓아 올려가면 된다.

    반응형

    댓글