2017-05-11 3 views
0

영화 검색을 제작하고 있습니다. themoviedb.org API를 사용하여 앱을 조작하십시오. Ajax 호출을 사용하여 입력 값을 변수로 가져와 URL에 공급해야하지만 다른 구성 요소에 속한 값을 가져 오는 방법을 알 필요가없는 영화 목록을 가져 오려면React : 한 구성 요소에서 입력 값을 가져 와서 다른 구성 요소에서 ajax 호출을 만드는 방법은 무엇입니까?

나는 광범위한 온라인 검색을 수행했지만, 주로 동일한 구성 요소 내에서 발생하는 경우를 참조하며 ref를 사용하는 것은 권장하지 않습니다.

그렇다면 하나의 구성 요소에서 입력 값 변수를 가져 와서 다른 매개 변수로 전달하고 URL 끝 부분에 첨부하는 가장 좋은 방법은 무엇입니까? 1) Keeping 글로벌 공간 청소 2) '반응 방식'에서 전체 앱 구성 3) 구성 요소를 분리 된 상태로 유지 ? 이 경우 라우터 재대동이 필요합니까?

import React from 'react'; 
    import './App.css'; 
    import axios from 'axios'; 


class SearchForm extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: ''}; 

    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 


    handleChange(event) { 
    this.setState({value: event.target.value}); 
    } 

    handleSubmit(event) { 
    console.log("state value is " + this.state.value); 

    var searchValue = this.movieName.value; 
    console.log("ref value is "+ searchValue) 

    event.preventDefault(); 
    } 


    render() { 

    return (
     <form onSubmit={this.handleSubmit}> 
     <label> 
      Name: 
      <input className="movieName" type="text" ref={(input) => { this.movieName = input; }} value={this.state.value} onChange={this.handleChange} /> 

     </label> 
     <input type="submit" value="Submit" /> 
     <h1>{this.state.value}</h1> 
     </form> 
    ); 
    } 
} 



class App extends NameForm{ /* I am extending NameForm to get access to input value, but probably coupling components too tight */ 
    constructor(props) { 
     super(props); 
     this.state ={ 
     movie:[] 
     }; 
    } 



componentDidMount() { 


    let searchInput = "land"; /* This should be from SearchForm's input value */ 


let sortByPop = "&sort_by=popularity.desc"; 
let requestUrl = 'https://api.themoviedb.org/3/search/movie?api_key=f8c4016803faf5e7f424abe98a04b8d9&query=' + searchInput + sortByPop; 

    axios.get(requestUrl).then(response => { 
     this.setState({movie: response.data.results}) 
    }); 



} 

render() { 

let baseImgURL = "https://image.tmdb.org/t/p/w185_and_h278_bestv2"; 
let posterImgPath = this.state.movie.map(movie => movie.poster_path); 


let posterLink = baseImgURL + posterImgPath; 

    return(

     <div className="App"> 
     <Header />  
     <SearchForm /> 

    <div> 
      {this.state.movie.map(movie => 
      <div className="movieTitle"> 
      <div className="movieCard"> 
      <img className="posterImg" src= {`https://image.tmdb.org/t/p/w185_and_h278_bestv2/${movie.poster_path}`} alt={movie.title} /> 
      <div className="searchFilmTitles" key={movie.id}>{movie.title}</div> 
      </div> 
      </div> 
      )} 
     </div> 

    </div> 
) 
} 

} 


export default App; 
+0

간단한 (정말) awnswer : 플럭스 REDUX : 일부 데이터 흐름 Managment를 같은 필요합니다. 그런 다음 액션을 호출하고이 액션에서 모든 AJAX 호출을 수행 한 다음 작업을 저장소로 보내면 필요한 구성 요소의 데이터가 변경됩니다. – Lojka

+0

부모가 그에 따라 상태를 업데이트 할 수 있도록 함수를'SearchForm' 구성 요소에 전달해야합니다. 이 경우,'SearchForm'은 부모 컴포넌트에 의해 제공되는 'onSearch' 프로퍼티를 가져야합니다. – Tristan

답변

1

componentDidMount 구성 요소가 페이지에 첨부 될 때 한 번만 호출됩니다. 따라서 검색 API를 호출하는 것이 정확한 장소가 아닙니다. 대신 사용자가 '제출'버튼을 클릭 할 때마다 호출해야합니다. 이를 위해서는 handleSubmit 트리거를 Call 요소를 SearchForm 구성 요소에 대한 소품으로 전달하여 App 구성 요소에 트리거를 버블 링해야합니다. 또한 state에 이미 검색 텍스트가있는 경우 ref을 사용할 필요가 없습니다.

SearchForm

class SearchForm extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {value: ''}; 

    this.handleChange = this.handleChange.bind(this); 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 


    handleChange(event) { 
    this.setState({value: event.target.value}); 
    } 

    handleSubmit(event) { 
    event.preventDefault(); 
    if(this.props.onSubmit && typeof this.props.onSubmit === "function"){ 
     this.props.onSubmit(this.state.value); 
    } 
    } 


    render() { 
    return (
     <form onSubmit={this.handleSubmit}> 
     <label> 
      Name: 
      <input className="movieName" type="text" value={this.state.value} onChange={this.handleChange} /> 
     </label> 
     <input type="submit" value="Submit" /> 
     <h1>{this.state.value}</h1> 
     </form> 
    ); 
    } 
} 

class App extends React.Component { /* I'm not sure why you extends NameForm and what NameForm does */ 
    constructor(props) { 
    super(props); 
    this.state = { 
     movie:[] 
    }; 
    this.handleSubmit = this.handleSubmit.bind(this); 
    } 

    handleSubmit(value) { 
    let searchInput = value // you get the value of movieName input here 

    let sortByPop = "&sort_by=popularity.desc"; 
    let requestUrl = 'https://api.themoviedb.org/3/search/movie?api_key=f8c4016803faf5e7f424abe98a04b8d9&query=' + searchInput + sortByPop; 

    axios.get(requestUrl).then(response => { 
     this.setState({movie: response.data.results}) 
    }); 
    } 

    render() { 

    let baseImgURL = "https://image.tmdb.org/t/p/w185_and_h278_bestv2"; 
    let posterImgPath = this.state.movie.map(movie => movie.poster_path); 
    let posterLink = baseImgURL + posterImgPath; 
    // I'm not sure why use need above code as you don't use it anywhere 

    return(
     <div className="App"> 
     <Header /> 
     <SearchForm onSubmit={this.handleSubmit}/> 
     <div> 
     {this.state.movie.map(movie => 
     <div className="movieTitle"> 
     <div className="movieCard"> 
     <img className="posterImg" src= {`https://image.tmdb.org/t/p/w185_and_h278_bestv2/${movie.poster_path}`} alt={movie.title} /> 
     <div className="searchFilmTitles" key={movie.id}>{movie.title}</div> 
     </div> 
     </div> 
     )} 
     </div> 
    </div> 
    ); 
    } 

} 
+0

완벽하게 작동합니다. - 감사합니다! 사이드 노트에서 플럭스 나 리듀 스 (redux)를 사용하는 것이 좋습니다. 아니면 필요하지 않지만 장기적으로 확장성에 도움이됩니까? – Amma

+0

당신을 진심으로 환영합니다. 이 경우 플럭스 나 리 펙스를 사용하는 것의 이점은 보이지 않습니다. 간단히 말해서 반응을 사용하면됩니다. 하지만 여러 구성 요소간에 상태를 공유해야하는 경우 이러한 상태 관리 라이브러리를 사용하는 것이 좋습니다. –

관련 문제