我正在使用 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/