我正在创建一个React应用程序,用于使用OMDb搜索电影。
我的应用程序分两个阶段工作:
下面是我的主要应用程序:
class Muuvies extends Component {
constructor() {
super();
this.state ={
movies: [],
error: "",
searchedFor: "",
};
this.search = this.search.bind(this);
}
search({data}) {
fetch(`http://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${data}&type=movie`)
.then(res => res.json())
.then(res => {
return res;
}).then(json => this.setState({
searchedFor: data,
movies: propOr([], 'Search', json),
error: json.Error
})).catch(err => this.setState({
error: 'Error Occurred: Try Again',
movies: [],
searchedFor: ''
}));
// if there wasn't an error, redirect to the Results page, passing what is returned from fetch().
}
render() {
return (
<Container>
<Logo role="img" aria-label="search"></Logo>
<SearchWrapper>
<Search search={this.search} />
{
this.state.error
? <Error><span role="img" aria-label="error" style={{marginRight: 2 + 'px'}}>⚠️</span>{this.state.error}</Error>
: null
}
</SearchWrapper>
</Container>
);
}
}
如何更改我的应用程序,以便如果用户提交表单并且没有错误(例如this.state.error
之后为fetch()
为空),则它将它们重定向到{ {1}}个组件?
Results
的内容:
Search.js
答案 0 :(得分:2)
鉴于您使用的是react-router-dom
,则可以使用history的push()
方法。这需要与包装组件withRouter一起使用,以暴露必要的道具。对于API调用/搜索的异步性质,还需要使用then()
做此操作:
import { withRouter } from 'react-router-dom';
class Muuvies extends Component {
constructor() {
super();
this.state ={
movies: [],
error: "",
searchedFor: "",
};
this.search = this.search.bind(this);
}
search({data}) {
fetch(`http://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${data}&type=movie`)
.then(res => res.json())
.then(res => {
return res;
}).then(json => {
// you may not need this if your are redirecting
this.setState({
searchedFor: data,
movies: propOr([], 'Search', json),
error: json.Error
}, () => {
this.props.history.push("/results"); // or whatever string path
});
}).catch(err => this.setState({
error: 'Error Occurred: Try Again',
movies: [],
searchedFor: ''
}));
// this would execute before API call/search is complete, need to do it in then()
}
render() {
return (
<Container>
<Logo role="img" aria-label="search"></Logo>
<SearchWrapper>
<Search search={this.search} />
{
this.state.error
? <Error><span role="img" aria-label="error" style={{marginRight: 2 + 'px'}}>⚠️</span>{this.state.error}</Error>
: null
}
</SearchWrapper>
</Container>
);
}
}
export default withRouter(Muuvies);
这是假设您为Results
组件/路径定义了Route:
import Results from './path/to/Results';
// ...
<Route path="/results" component={Results} />
您还可以在render()
方法中使用Redirect组件,也许基于某些状态值:
import { Redirect } from 'react-router-dom';
// ...
render() {
// check for error and maybe some other flag(s) such as a boolean property
if (!this.state.error && this.state.submitted && this.state.movies.length > 0) {
return <Redirect to={{ pathname: '/results', state: { movies: this.state.movies } }} />
}
// else render form or error maybe
}
这表明,如果您打算在组件级别导航至“ /结果”或任何路径,则可能不需要设置状态。如有必要,可以将state作为第二个参数传递给history.push(path, state)
方法。
希望有帮助!
答案 1 :(得分:0)
您可以在此处编写代码:
search({data}) {
fetch(`http://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${data}&type=movie`)
.then(res => res.json())
.then(res => {
return res;
}).then(json => {
this.setState({
searchedFor: data,
movies: propOr([], 'Search', json),
error: json.Error
});
//------
//Write your code here, because if you got there, then there was no error at none of the "then" above
//Or if a success response can contain an error field, you can check it with an if statement
//------
}).catch(err => this.setState({
error: 'Error Occurred: Try Again',
movies: [],
searchedFor: ''
}));
代码取决于您如何构造项目以及使用的库。