React 프로젝트: 영화 앱

안녕하세요 👋, dev.to의 첫 번째 게시물로 React와 TypeScript를 사용하여 영화 앱을 만드는 방법에 대한 간단한 자습서를 공유하기로 결정했습니다.

데모 https://movie-app-majuran.netlify.app 🚀



Github에서 사용 가능한 소스 코드: Here !

설정



코딩을 시작하기 전에 프로젝트를 설정해 봅시다.

Create React App으로 프로젝트 생성:



나는 종종 (항상은 아니지만 😁) Create React App을 사용하여 React 프로젝트를 시작합니다.

프로젝트 실행을 생성하려면 다음을 수행하십시오.

npx create-react-app my-movie-app --template typescript


API:



프런트엔드는 API에서 데이터를 가져와야 합니다. 저는 선택했습니다TMDb 🎬 : 무료입니다. API 키를 받으려면 계정을 생성하기만 하면 됩니다.
.env 파일에서 API 키를 환경 변수로 사용하십시오.

REACT_APP_API_KEY=YOUR_API_KEY


구성이 완료되었으므로 코딩을 시작하겠습니다. 💻

상태 관리



우리의 앱 구성 요소는 그들 사이에서 통신할 것입니다.
이를 처리하려면 상태 관리가 필요합니다. 이를 위해 context APIstate hooks를 결합할 것입니다.

In case, you are not familiar with react hooks. I encourage you, to read ➡️ React Hooks and Context API



// create context
export const MoviesContext = React.createContext<{
  movies: Movie[];
  updateMovies: Function;
}>({
  movies: [],
  updateMovies: Function,
});

function App() {
// get default values
  useEffect(() => {
    discoverMovies()
      .then(setMovies)
      .catch((_) => setMovies([]));
  }, []);

// use state hook
  const [movies, setMovies] = useState<Movie[]>([]);

  return (
  // Provide to the all project: 
  // - movies an array of Movie, 
  // - updateMovies : function to update the movies list
    <MoviesContext.Provider value={{ movies, updateMovies: setMovies }}>
      <div className="App">
        <Header></Header>
        <Catalog></Catalog>
      </div>
    </MoviesContext.Provider>
  );
}



구성품



Don’t be afraid to split components into smaller components. (React Doc)



React에서는 UI를 구성 요소별로 분할하는 것이 중요하므로 필요한 구성 요소 수를 확인하겠습니다.


보시다시피 세 가지 구성 요소가 눈에 띕니다.
  • Header
  • Search
  • Catalog

  • 구성 요소를 만들 때 묻는 질문:
    내 구성 요소는 무엇을 해야 합니까?! 🤔

    헤더



    헤더 구성 요소는 매우 간단하며 프로젝트 제목과 검색 구성 요소가 포함되어 있습니다.

    export const Header = () => {
      return (
        <div className="header">
          <h1 className="header__title">Movie App</h1>
          <div className="header__search">
            <Search></Search>
          </div>
        </div>
      );
    };
    
    


    검색



    검색 구성 요소는 다음과 같아야 합니다.
  • 입력 필드 표시
  • 사용자 검색 저장
  • 이 검색으로 API를 쿼리합니다
  • .
  • 영화 목록 업데이트

  • 입력 상태를 저장하기 위해 이 구성 요소에서 useState 후크를 사용합니다.

    export const Search = () => {
      const [search, setSearch] = useState("");
      // Consume our context to get updateMovies function
      const { updateMovies } = useContext(MoviesContext); 
    
      const handleOnSubmit = (event: React.FormEvent) => {
        event.preventDefault();
        if (search) {
          searchMovies(search).then((movies) => {
            updateMovies(movies);
          });
        }
    
      return (
        <div>
          <form name="form" onSubmit={(e) => handleOnSubmit(e)} noValidate>
            <input
              type="text"
              name="movie"
              className="search__input"
              placeholder="Search movie ... "
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
          </form>
        </div>
      );
    };
    
    


    목록



    카탈로그 구성 요소는 다음과 같아야 합니다.
  • 컨텍스트에서 동영상 가져오기
  • 이 어레이의 루프

  • export const Catalog = () => {
      // Consume the context to get list of movies.
      const { movies } = useContext(MoviesContext);
    
      return (
        <div className="catalogContainer">
          {movies.map((movie) => (
            <div className="catalog__item" key={movie.id}>
              <div className="catalog__item__img">
                <img src={movie.picture || imgPlaceholder} alt={movie.title} />
                <div className="catalog__item__resume">{movie.resume}</div>
              </div>
              <div className="catalog__item__footer">
                <div className="catalog__item__footer__name">
                  {movie.title} ({new Date(movie.date).getFullYear()})
                </div>
                <div className="catalog__item__footer__rating">{movie.rating}</div>
              </div>
            </div>
          ))}
        </div>
      );
    };
    
    


    API에서 가져오기() 데이터



    데이터용 API를 가져오기 위해 서비스를 생성해 보겠습니다.

    const movieApiBaseUrl = "https://api.themoviedb.org/3";
    
    export function searchMovies(search: string): Promise<Movie[]> {
      return fetch(
        `${movieApiBaseUrl}/search/movie?query=${search}&api_key=${process.env.REACT_APP_API_KEY}`
      )
        .then((res) => res.json())
        .catch((_) => {
          return [];
        });
    }
    
    export function discoverMovies(): Promise<Movie[]> {
      return fetch(
        `${movieApiBaseUrl}/discover/movie?sort_by=popularity.desc&api_key=${process.env.REACT_APP_API_KEY}`
      )
        .then((res) => res.json())
        .then((response) => mapResult(response.results))
        .catch((_) => {
          return [];
        });
    }
    


    결론



    이 튜토리얼을 통해 다음과 같은 몇 가지 중요한 개념을 제시하려고 했습니다.
  • React 컨텍스트 API
  • 반응 후크
  • API 호출을 수행하기 위한 함수 가져오기

  • 더 나아가려면



    기술 향상을 위한 몇 가지 추가 아이디어:
  • 핸들 결과 없음
  • 용도Redux
  • 페이지 매김

  • 원천 :


  • 이 프로젝트를 Github에 복제할 수 있습니다.
  • 좋은 웹페이지 즐겨찾기