MovieApp 검색 기능 구현

Hyun·2021년 9월 8일
0

리액트 [Movie App]

목록 보기
7/10

기존의 movie를 받아오는 주소에서 YTS사이트의 api정보글을 참고하여 state에 있는 input에 입력된 값을 이용해 그 값과 관련된 영화들을 가져오는 기능을 구현했다. getMovies함수를 조금 수정하여 사용하였다. YTS API 주소

getMovies = async () => {
   const {data: {data: {movies}}} = await axios.get("https://yts.mx/api/v2/list_movies.json?sort_by=rating");  
   this.setState({movies, isLoading: false})
}

getSearchedMovies = async (e) => {
   e.preventDefault();
   this.setState({isLoading: true})
   const {data: {data: {movies}}} = await axios.get(`https://yts.mx/api/v2/list_movies.json?query_term="${this.state.input}"`);  
   this.setState({movies, isLoading: false})
}

검색창을 만들기위해 form태그와 input태그를 사용하였고, 각각의 태그에 onSumbit, onChange속성을 주어 state에 input value를 넣고 submit을 했을때 onSubmit안의 함수가 실행되도록 했다.
(태그의 속성이 함수를 호출할때 함수에 자동적으로 event가 인자로 입력된다.)

goInput = (e) => {
  this.setState({input: e.target.value})
}
<div class="innerContainer">
          <div className="search">
            <form onSubmit={this.getSearchedMovies}>
              <input className="input" type="text" onChange={this.goInput}/>
              <input type="submit" value="submit"/>
                //input tag도 submit을 하는 버튼용으로 쓸 수 있다는 것을 알게되었다.
            </form>
          </div>
          <div className="movies">
            {movies.map(movie => (
       	     <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>
</div>

도중에 "TypeError Cannot read property 'setState' of undefined" 가 발생했는데 알아보니 호출하는 함수가 bind되지 않아서 그렇다고 한다. 예를 들어 onChange에 연결할 함수로 this.handleChange를 지정했다면 this.handleChange함수는 아래 두 가지 방법 중 한가지 방법으로 구현되어 있어야 한다.

  1. 생성자에서 바인딩 해주기
this.handleChange = this.handleChange.bind(this);
  1. 화살표 함수로 구현
    화살표 함수로 구현하면 자동으로 바인딩이 되기 때문에 생성자에서 명시적으로 바인딩을 해주지 않아도 된다. 달리 말해 화살표 함수를 쓰지 않는다면 생성자에서 바인딩을 해줘야 한다.
handleChange = (props) => {
 ...
}

참고자료

Full Code

...
class App extends React.Component{
state = {
  isLoading: true,
  moives: [],
  input: "good"
}
getMovies = async () => {
   const {data: {data: {movies}}} = await axios.get("https://yts.mx/api/v2/list_movies.json?sort_by=rating");  
   this.setState({movies, isLoading: false})
}
getSearchedMovies = async (e) => {
   e.preventDefault();
   this.setState({isLoading: true})
   const {data: {data: {movies}}} = await axios.get(`https://yts.mx/api/v2/list_movies.json?query_term="${this.state.input}"`);  
   this.setState({movies, isLoading: false})
}
goInput = (e) => {
  this.setState({input: e.target.value})
}
componentDidMount(){
  console.log("component DId Monnt");
 this.getMovies();
}
render(){
  console.log("rendering");
    const { isLoading, movies } = this.state;
    return(
      <section className="container">{this.state.isLoading ? 
      <div className="loader">
        <span className="loader_text">Loading...</span>
      </div> 
      : (
        <div class="innerContainer">
          <div className="search">
            <form onSubmit={this.getSearchedMovies}>
              <input className="input" type="text" onChange={this.goInput}/>
              <input type="submit" value="submit"/>
            </form>
          </div>
          <div className="movies">
          {movies.map(movie => (
          <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>
      </div>
      )}
      </section>
    ) 
  }
}
export default App;
profile
better than yesterday

0개의 댓글