如果输入已提交,则重定向到其他路由 - React 路由器



我正在创建一个 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.errorfetch()之后为空(,然后它会将它们重定向到Results组件?

Search.js内容:

class Search extends Component {
constructor(props) {
super(props);
this.state = {
data: '',
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({[e.target.name]: e.target.value});
}
handleSubmit(e) {
e.preventDefault();
this.props.search(this.state);
this.setState({ data: '' });
}
render () {
return (
<StyledForm onSubmit={this.handleSubmit}>
<StyledSearch id="data" type="text"
name="data"
placeholder="Search for Muuvies."
value={path(['state', 'data'], this)}
onChange={this.handleChange}
autoComplete="off"
autoFocus={true}
/>
</StyledForm>
)
}
}

鉴于您正在使用react-router-dom您可以使用历史记录的push()方法。这需要与带有路由器的包装组件一起使用,以暴露必要的道具。这也需要通过then()API 调用/搜索的异步性质来完成:

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组件/路径定义了路由:

import Results from './path/to/Results';
// ...
<Route path="/results" component={Results} />

您还可以在render()方法中使用重定向组件,可能基于某些状态值:

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
}

正在演示,如果您计划在组件级别导航到"/results"或任何路径,则可能不需要设置状态。如有必要,可以将状态作为第二个参数传递给history.push(path, state)方法。

希望对您有所帮助!

你可以在这里编写代码:

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

代码取决于您如何构建项目以及您使用哪些库。