[인기 영화 검색 사이트] 제작 프로젝트 #5 - 코드 리팩토링(Code Refactoring)

G_NooN·2024년 1월 10일
0

프로젝트

목록 보기
5/13

프로젝트의 해설 강의를 시청하고, 코드를 어떤 방식으로 구현해야 하는지 깨닫게 되었다.
그래서 시청 직후, 코드 리팩토링(Code Refactoring)을 실시하였다.

작업 디렉토리 및 기능 분리

작업 디렉토리 분리

하나의 디렉토리에서 html, css, js 파일을 모두 관리했던 기존 방식에서,
CSS 파일을 관리하는 style 폴더, js 파일을 관리하는 src 폴더를 생성하여 HTML과 분리했다.

기존개선 방식
index.htmlindex.html
main.css/style/main.css
main.js/src/main.js

기능 분리와 모듈(module) 사용

JavaScript의 기능 별로 파일을 분리하여 가독성이 편하도록 하였다.

AS-ISTO-BE
main.js
main.jssearch.js (검색 기능)
showMovies.js(영화 출력 기능)

또한, 모듈(module)을 사용하여 각 기능들을 main.js로 import하여 사용했다.

// search.js
export const showSearchResult = (searchKeyword) => {...};

// main.js
import { generateMovieList } from "./showMovies.js";
import { showSearchResult } from "./search.js";

Grid 설정

한 줄에 1개의 영화만 나오던 화면을 grid를 사용하여 한 줄에 여러 개의 영화가 나오도록 설정했다.

#movie-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 2rem;

  padding: 2rem;
}

비동기 함수(async/await) 사용

async, await 키워드를 사용하여 비동기 함수 형태로 함수를 분리하였다.

// AS-IS
const options = {
  method: 'GET',
  headers: {
    accept: 'application/json',
    Authorization: 'Bearer my_api_key'
  }
};

fetch(url, options)
  .then((res) => res.json())
  .then((data) => {
    const movie_data = data["results"];
}
        
// TO-BE
const generateMovieList = async () => {
  const movies = await fetchMovieData();
}

async function fetchMovieData() {
  const options = {
    method: "GET",
    headers: {
      accept: "application/json",
      Authorization:
        'Bearer my_api_key'
    },
  };

const movie_data = await fetch(url, options).then((data) => data.json());

return movie_data.results;
}

검색 결과 출력

기존의 새로운 배열을 출력하는 방식이 아닌, display style을 변경하는 방식으로 개선하였다.

// AS-IS
function showSearchResults() {
  fetch(url, options)
    .then((res) => res.json())
    .then((data) => {
      const movie_data = data["results"];
      const searched_list = movie_data.filter((movie) => {
        return (
          movie.title.includes(inputText.value) ||
          movie.original_title.toUpperCase().includes(inputText.value.toUpperCase()
        );
      });
    
      const searched_result = searched_list.map((movie) => {
        let movie_html = `
    <div class="movie_card"token interpolation">${movie.title}] 의 Movie ID : ${movie.id}')">
      <div class="movie_content">
        <h2>${movie.title} (${movie.original_title})</h2>
        <p><strong>개봉일</strong> : ${movie.release_date} / <strong>평점</strong> : ${movie.vote_average}</p>
        <p>${movie.overview}</p>
      </div>
      <div class="movie_img">
        <img src="https://image.tmdb.org/t/p/w185${movie.poster_path}" />
      </div>
    </div>`;
        
        return movie_html;
      });
    
      movie_list.innerHTML = "":
      
      searched_result.forEach((movie) => {
        movie_list.innerHTML += movie;
      });
    })
    .catch((err) => console.log(err));
}

// TO-BE
// 검색 결과 출력
const showSearchResult = (searchKeyword) => {
  const movieItems = document.querySelectorAll(".movie-item");

  movieItems.forEach((item) => {
    const title = item.querySelector(".movie-title").textContent; // 한국어 제목
    const originalTitle = item.querySelector(".movie-original-title").textContent.toUpperCase(); // 원제
    const searchedValue = searchKeyword;

    if (title.includes(searchedValue) || originalTitle.includes(searchedValue.toUpperCase())) {
      item.style.display = "block";
    } else {
      item.style.display = "none";
    }
  });
};

영화 카테고리 추가

fetch할 URL 입력값을 선택할 수 있게 하여 카테고리를 설정할 수 있게 하였다.

<!-- index.html -->
<ul class="sort-list">
  <li id="popular">Popular</li>
  <li id="topRated">Top Rated</li>
</ul>
// showMovies.js
const url = `https://api.themoviedb.org/3/movie/${urlInfo}?language=ko-KR`;

const generateMovieList = async (urlInfo) => {
  const movies = await fetchMovieData(urlInfo);
}

// main.js
const $popular = document.querySelector("#popular");
const $topRated = document.querySelector("#topRated");

$popular.addEventListener("click", (event) => {
  event.preventDefault();
  generateMovieList("popular");
});

$topRated.addEventListener("click", (event) => {
  event.preventDefault();
  generateMovieList("top_rated");
});

결과 화면

기존 ver.

개선 ver.

profile
쥐눈(Jin Hoon)

0개의 댓글