javascript - react : how to get input value from one component to make the ajax call in another component?

标签 javascript ajax reactjs variables react-router

我正在使用 themoviedb.org API 构建一个电影搜索 React 应用程序。为了进行 ajax 调用来提取电影列表,我需要将输入值作为变量获取并提供给 url,但不确定如何获取属于另一个组件的值。

我进行了广泛的在线搜索,但它们主要指的是发生在同一组件内的情况,并且不鼓励使用 ref 。

那么从一个组件获取输入值变量以传递到另一个组件并附加到 url 末尾的最佳方法(或至少是最常见或最简单的方法)是什么,同时: 1)保持全局空间清洁 2)以“React方式”组织整个应用程序 3)保持组件解耦 ? 在这种情况下,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 仅被调用一次。所以这不是调用搜索 API 的正确位置。相反,您应该在每次用户单击“提交”按钮时调用它。为此,您需要通过将回调方法作为 props 传递给 SearchForm 组件,将 handleSubmit 触发器冒泡到 App 组件。此外,您不需要使用 ref,因为您的 state 中已经有搜索文本。

搜索表单

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

}

关于javascript - react : how to get input value from one component to make the ajax call in another component?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43906265/

相关文章:

javascript - 在下一次迭代之前等待 ajax 成功

javascript - 没有路由器如何获取URL参数?

javascript - Jquery did() 的正确语法是什么?

javascript - 我无法输出 Handlebars 模板中的数据

javascript - ajax 请求完成后 Jquery 延迟对象解析

javascript - 使用nodejs查询MongoDb

javascript正则表达式验证带空格的字母数字文本并拒绝特殊字符

javascript - 如果页面 url = 列表中的 anchor ,则触发鼠标悬停 + 加粗

javascript - 创建一个 Axios 帖子以使用 Dropzone 发送上传的文件,以便 Scala 函数处理相应的请求

javascript - 未捕获的 TypeError : this. props.populateAction 不是函数,React