React image


React로 영화 소개 앱 만들기 - 01

우선적으로, render 함수가 호출되고 나서 어떤 함수가 실행되어야 하는지 정의해줬다. state 객체에는 로딩 여부를 체크하는 요소가 있고, 영화 데이터를 담을 빈 배열을 만들어주었다. render 함수 내부에서는 브라우저에 보일 요소들을 return 해주고, 각각의 엘리먼트에 className을 지정해주었다. 1

class App extends React.Component {

   state = {
      isLoading: true,
      movies: []
   }

   componentDidMount() {

      // render가 mount(생성)된 이후 즉시 실행될 구문이 들어온다.

   }

   render() {
      
      // render 함수에서 사용할 state의 키들을 정의해준다. 
      const { isLoading, movies } = this.state;

      return <section className='container'> 
         { isLoading ?
            ( <div className="loader">
               <span className="loader_text">Loading</span>
            </div> ) : (

            )
         }
   }
}


React로 영화 소개 앱 만들기 - 02

랜더링을 하기 위한 기본세팅은 마쳤다. 이제 componentDidMount()로 실행시킬 함수를 구성해야 한다. 그 함수는 비동기로 처리가 되는데, API를 이용하여 JSON 데이터를 받아와야 한다. 그 다음 기존의 state를 다시 set 해주는 this.setState() 를 처리해주면 된다.

비동기를 처리하려면 내가 이전에 배우지 못했던 새로운 문법이 필요했다. 그것은 바로 async/await 였다. 말 그대로 ‘async를 진행할 건데, 특정 await를 기다려줘’와 같은 의미이다.

데이터를 제공하는 API는 data > data > movies 의 구조로 이루어져 있고, 최종 movies 객체에서 각각의 영화 정보를 확인할 수 있었다. 프리코스에서도 배웠지만, JSON과 같은 데이터를 다룰 때 중요한 것은 데이터의 중첩적인 구조이다!

   
   getMovies = async() => {
      const { data: { data: { movies }}} = await axios.get(url 주소)

      this.setState({ movies, isLoading: false})
      // movies 는 movies: movies와 같은 표현이다.
      // setState는 await로 비동기가 이뤄진 다음 작동하게 된다.
   } 

   componentDidMount() {
      this.getMovies();
   }


React로 영화 소개 앱 만들기 - 03

이제는 로딩 이후에 받아온 API의 데이터를 UI에 뿌려주어야 한다. 그래서 movies.js 파일을 만들어서 <Movie />라는 함수형 컴포넌트를 만들어주었다. 함수형 컴포넌트에는 역시나 props에 대한 정의와 사용이 중요했다.

영화 API의 데이터 중에서 사이트에 보여질 데이터는 title, year, title, summary, poster, genre 로 정했다. 그중에서 genre는 한 영화에 여러가지 요소가 있어서 배열 처리를 해주었다.

function Movie({ id, year, title, summary, poster, genres }) {
   return <div>
      < img src={poster} alt={title} title={title} />
      <div>
         <h3> { title } </h3>
         <h5> { year } </h5>
         <ul>
            {genres.map((genre, idx) => {
               <li key={idx}> { genre } </li>
            })}
         </ul>   
         <p> { summary.slice(0, 180) } </p>
      </div>
   </div>
}


React 시리즈 01에서 함수형 컴포넌트를 정리하면서도 말했지만, React는 데이터들의 고유한 정보를 중요시 하기 때문에 li 태그 안에 map 메소드가 받는 인덱스 번호를 넣어줬다. summary의 경우에는 영화별로 길이가 다 다르기 때문에 일관성을 유지하고자 slice 메소드를 활용했다.


React로 영화 소개 앱 만들기 - 04

이제 남은 것은 App.js에 render 함수를 완성시키는 것이다. componentDidMount() 의 호출로 인해서 state 객체 안에 만들어둔 movies 배열에 데이터가 반영되었다.

로딩이 끝나면 (여기서는 API의 데이터가 다 받아와지면) getMovies() 함수가 작동하고 Movie 컴포넌트가 JSX에 의해서 브라우저에 떠오르게 된다.

   : (
          <div className="movies">
            {movies.map(movie => {
              return < Movie key={movie.id}
                id={movie.id}
                year={movie.year}
                title={movie.title}
                summary={movie.summary}
                poster={movie.medium_cover_image}
                genres={movie.genres} />
            })}
          </div>)}
    </section >


코드스테이츠 프리코스에서 배운 map 메소드는 정말 유용하게 잘 쓰이고 있다. 내가 이 노마더코더의 강좌를 따라갈 수 있었던 것도 코드스테이츠 프리 과정을 착실하게 밟아갔기 때문이 아닌가 한다. 😆


  1. React에서는 css의 class와 컴포넌트를 구성하는 class를 동일하게 보기 때문에 className으로 지정해준다.