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

时间:2018-09-27 19:31:20

标签: reactjs react-router

我正在创建一个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

2 个答案:

答案 0 :(得分:2)

鉴于您使用的是react-router-dom,则可以使用historypush()方法。这需要与包装组件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: ''
    }));

代码取决于您如何构造项目以及使用的库。