我正在创建一个搜索电影的应用。现在一切都在一个班级。我想制作一部电影"我搜索电影时只渲染一次的组件。电影渲染时我对OMDB进行了异步调用。我只希望这发生一次,只有当我点击搜索按钮时才会发生。
到目前为止,我有它工作,只有ReactJS一遍又一遍地渲染Movie组件,这意味着我的应用程序不断将API调用发送到OMDB数据库。这是我的代码:
import React, { Component } from 'react';
import { BrowserRouter as Router, Link, NavLink } from 'react-router-dom';
import Route from 'react-router-dom/Route';
import './App.css';
import language from './Components/Language';
import Navbar from './Components/Navbar';
import NavbarSimple from './Components/NavbarSimple';
class App extends Component {
constructor(){
super();
this.state = {
movieSearchTerm: '',
error: '',
languageIndex: 0,
searchSubmitted: false,
title: "",
year: "",
rated: "",
released: "",
runtime: "",
genre: "",
director: "",
writer: "",
actors: "",
plot: "",
language: "",
awards: "",
poster: "",
list_ratings: "",
imdbRating: "",
imdbVotes: "",
type: ""
}
this.onChangeMovieInput = this.onChangeMovieInput.bind(this);
this.onSubmitMovieForm = this.onSubmitMovieForm.bind(this);
this.switchLanguageTo = this.switchLanguageTo.bind(this);
this.setSearchSubmittedTo = this.setSearchSubmittedTo.bind(this);
}
switchLanguageTo(id){
this.setState({
languageIndex: id
});
}
getMovie(title){
console.log("Searching movie '" + title + "'");
var xhr = new XMLHttpRequest();
var json_obj, status = false;
xhr.open("GET", "http://www.omdbapi.com/?t=" + title + "&apikey=6c3a2d45", true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var movie = JSON.parse(xhr.responseText);
status = true;
console.log(movie);
if(movie.Error){
this.setState({
error: movie.Error
});
} else {
this.setState({
title: movie.Title,
year: movie.Year,
rated: movie.Rated,
released: movie.Released,
runtime: movie.Runtime,
genre: movie.Genre,
director: movie.Director,
writer: movie.Writer,
actors: movie.Actors,
plot: movie.Plot,
language: movie.Language,
awards: movie.Awards,
poster: movie.Poster,
// list_ratings: movie.Ratings // Need to come up with a solution to render arrays as csv.
imdbRating: movie.imdbRating,
imdbVotes: movie.imdbVotes,
type: movie.Type
});
}
} else {
console.log(xhr.status + ": " + xhr.statusText);
}
}
}.bind(this);
xhr.onerror = function (e) {
console.log(xhr.status + ": " + xhr.statusText);
};
xhr.send(null);
}
onChangeMovieInput(e){
this.setState({
movieSearchTerm: e.target.value
})
}
onSubmitMovieForm(e){
e.preventDefault();
console.log("Movie to be searched: " + this.state.movieSearchTerm);
this.setState({searchSubmitted: true});
// this.getMovie(this.state.movieSearchTerm);
}
setSearchSubmittedTo(value){
this.setState({searchSubmitted: value});
}
render() {
if(this.state.searchSubmitted === false){
return (
<div>
<Navbar languageIndex={this.state.languageIndex} switchTaal={this.switchLanguageTo} />
<div className="App container-fluid mt-large">
{/* START SEARCH COMPONENT */}
<div className="row">
<div className="col-xs-12">
<form onSubmit={this.onSubmitMovieForm}>
<input type="text" className="width-100p" onChange={this.onChangeMovieInput} />
<button type="submit" className="width-100p btn btn-primary">Search</button>
</form>
</div>
</div>
{/* EINDE SEARCH COMPONENT */}
<div className="row">
{/* START MOVIE COMPONENT */}
<div className="movie">
<div className="row">
<div className="col-xs-12">
<p>{language[this.state.languageIndex].searchMovieInstruction} <span className={this.state.error===""?"hidden":"visible"}>Error: {this.state.error}</span></p>
</div>
</div>
</div>
{/* EINDE MOVIE COMPONENT */}
</div>
</div>
</div>
);
// EINDE RETURN
} else {
return (
<div>
<Navbar languageIndex={this.state.languageIndex} switchTaal={this.switchLanguageTo} />
<div className="App container-fluid mt-large">
{/* START SEARCH COMPONENT */}
<div className="row">
<div className="col-xs-12">
<form onSubmit={this.onSubmitMovieForm}>
<input type="text" className="width-100p" onChange={this.onChangeMovieInput} />
<button type="submit" className="width-100p btn btn--primary">Search</button>
</form>
</div>
</div>
{/* EINDE SEARCH COMPONENT */}
<div className="row">
{/* I WANT THIS COMPONENT TO RENDER AS "<Movie title={this.state.movieSearchTerm} /> only when I click on search. The movie component then makes a call to the OMDB resulting in the search result. */}
{/* START MOVIE COMPONENT */}
<div className="movie">
<div className="row">
<div className="col-xs-12 col-sm-3 col-md-2">
<img src={this.state.poster} className="img-responsive movie--image" />
</div>
<div className="col-xs-12 col-sm-9 col-md-10">
<div className="flex flex-justify-between flex-align-center">
<div className="flex-padding-left">
<h3>{this.state.title} <span style={{textTransform:'capitalize'}}>{"(" + this.state.type}</span> - {this.state.year + ")"}</h3>
</div>
<div className="flex-padding-right">
Rating
</div>
</div>
<div className="row">
<div className="col-xs-12">
<p className="text--subtext">{this.state.runtime} | {this.state.genre} | {this.state.released}</p>
</div>
</div>
<div className="row">
<div className="col-xs-12 mt-small">
{this.state.plot}
</div>
</div>
<div className="row">
<div className="col-xs-12 col-sm-6">
<ul className="list">
<li>Director: {this.state.director}</li>
<li>Writer: {this.state.writer}</li>
<li>Language: {this.state.language}</li>
<li>Actors: {this.state.actors}</li>
</ul>
</div>
</div>
<div className="row">
<div className="col-xs-12 box">
List of ratings
</div>
</div>
<div className="row">
<div className="col-xs-12 box">
Awards
</div>
</div>
</div>
</div>
</div>
{/* EINDE MOVIE COMPONENT */}
</div>
</div>
</div>
);
// EINDE RETURN
}
}
isEmpty(variable){return (variable == "" || variable === "" || variable == undefined || variable === undefined || variable == null || variable === null) == true;}
}
export default App;
如果有任何不清楚的地方,请告诉我,我会在有空的时候更新我的帖子。