【问题标题】:Redirect automatically from one component to another one after few seconds - react几秒钟后自动从一个组件重定向到另一个组件 - 反应
【发布时间】:2019-01-19 11:03:15
【问题描述】:

几秒钟后,我尝试将用户从一个组件重定向到另一个组件。

用户登陆一个页面,几秒钟后他会自动重定向到另一个页面。 我想在一个动作中重定向,但我不确定这是否是最好的主意(如果你有更简单的方法,我很感兴趣)。

到目前为止我的代码:

一个基本组件:

import React, { Component } from "react";
import { connect } from "react-redux";
import { withRouter } from "react-router-dom";
import { redirectToProfile } from "../../actions/searchActions";

class Search extends Component {
  componentDidMount() {
    setTimeout(this.props.redirectToProfile(this.props.history), 3000);
  }
  render() {
    return (
      <div>
        <h1>search page</h1>
      </div>
    );
  }
}

export default connect(
  null,
  { redirectToProfile }
)(withRouter(Search));

和行动:

export const redirectToProfile = history => {
  history.push("/");
};

到目前为止,我收到一条错误消息:

动作必须是普通对象。使用自定义中间件进行异步操作。

经过一些研究,我发现有些人使用中间件 thunk 解决了问题,但我已经在使用它,所以我不知道该怎么做。 感谢您的帮助。

【问题讨论】:

    标签: reactjs redux redux-thunk


    【解决方案1】:

    如果您已经在使用 redux thunk 并且它已包含在您的项目中,您可以按以下方式创建操作。

    export const redirectToProfile = history => {
      return (dispatch, setState) => {
        history.push('/');
      }
    };
    
    // shorter like this.
    export const redirectToProfile = history => () => {
      history.push('/');
    }
    
    // and even shorter...
    export const redirectToProfile = history => () => history.push('/');

    替代方案:
    如果您调整搜索组件的默认导出,您也可以直接在组件中调用history.push('/');。这是首选,因为您没有创建额外操作并通过 redux 调度它的开销。

    将您的导出更改为...

    export default withRouter(connect(mapStateToProps)(Search));
    

    然后在你的组件中使用它...

    componentDidMount() {
      setTimeout(this.props.history.push('/'), 3000);
    }
    

    【讨论】:

    • 谢谢。重定向有效,我不再有错误消息。但是 setTimeout 函数不起作用,我不明白为什么。我应该直接在动作中使用它还是我在某个地方犯了错误?
    【解决方案2】:

    为什么不使用react-router 提供的&lt;Redirect/&gt; 组件呢?我认为这更清晰,更符合 React 的声明性模型,而不是在命令式 thunk/action 中隐藏逻辑。

    class Foo extends Component {
      state = {
        redirect: false
      }
    
      componentDidMount() {
        this.id = setTimeout(() => this.setState({ redirect: true }), 1000)
      }
    
      componentWillUnmount() {
        clearTimeout(this.id)
      }
    
      render() {
        return this.state.redirect
          ? <Redirect to="/bar" />
          : <div>Content</div>
      }
    }
    

    【讨论】:

    • 谢谢杰德,确实这样更清晰,而且效果很好!
    【解决方案3】:
    state = {
        redirect: false // add a redirect flag
    };
    
    componentDidMount() {
        // only change the redirect flag after 5 seconds if user is not logged in
        if (!auth) {
            this.timeout = setTimeout(() => this.setState({ redirect: true }), 5000);
        }
    }
    
    componentWillUnmount() {
        // clear the timeer just in case
        clearTimeout(this.timeout);
    }
    
    render() {
        // this is the key:
        // 1. when this is first invoked, redirect flag isn't set to true until 5 seconds later
        // 2. so it will step into the first else block
        // 3. display content based on auth status, NOT based on redirect flag
        // 4. 5 seconds later, redirect flag is set to true, this is invoked again
        // 5. this time, it will get into the redirect block to go to the sign in page
        if (this.state.redirect) {
            return <Redirect to="/signin" />;
        } else {
            if (!auth) {
                return (
                    <div className="center">
                        <h5>You need to login first to register a course</h5>
                    </div>
                );
            } else {
                return <div>Registration Page</div>;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-08-11
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 2019-03-08
      • 2021-05-01
      相关资源
      最近更新 更多