简体   繁体   English

React:如何从一个组件获取输入值以在另一个组件中进行Ajax调用?

[英]React : how to get input value from one component to make the ajax call in another component?

I am building a movie search React app using themoviedb.org API. 我正在使用themoviedb.org API构建电影搜索React应用。 in order to an make ajax call to pull the list of movies I need to get input value as a variable and feed to the url, but not sure how to fetch a value that belongs to another component. 为了进行ajax调用以提取电影列表,我需要获取输入值作为变量并输入到url,但不确定如何获取属于另一个组件的值。

I've made an extensive online search, but they mainly refer to the case when it happens inside the same component, and using ref is discouraged. 我进行了广泛的在线搜索,但是它们主要是指这种情况发生在同一组件内,并且不建议使用ref。

So what would be the best way (or at least most common or the simplest way) to fetch the input value variable from one component to pass down to another and attach to the end of url, while: 1) Keeping global space clean 2) Organizing the entire app in 'React way' 3) Keeping components decoupled ? 那么什么是从一个组件中获取输入值变量并向下传递到另一个组件并附加到url末尾的最佳方法(或至少是最常见或最简单的方法),同时:1)保持全局空间整洁2)以“反应方式”组织整个应用程序3)保持组件分离? Would React Router necessary in this case? 在这种情况下,React Router是否必要?

   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;

componentDidMount get called only once when your component get attached to the page. componentDidMount被调用,只有当您的组件获得附加到页面一次。 So it's not the correct place to call you search API. 因此,这不是调用您的搜索API的正确位置。 Instead, you should call it every time when the user clicks 'submit' button. 相反,您应该在用户每次单击“提交”按钮时调用它。 For that, you need to bubble handleSubmit trigger to App component by passing a callback method as a prop to SearchForm component. 为此,您需要通过将回调方法作为道具传递给SearchForm组件,使handleSubmit触发器冒泡到App组件。 Also, you don't need to use ref as you already have search text in your state . 另外,您不需要使用ref因为您已经在state找到了搜索文本。

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>
    );
  }
}

App 应用程式

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>
    );
  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM