几秒钟后自动从一个组件重定向到另一个组件 - 反应

Redirect automatically from one component to another one after few seconds - react

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

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

到目前为止我的代码:

一个基本组件:

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("/");
};

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

Actions must be plain objects. Use custom middleware for async actions.

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

如果您已经在使用 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);
}

为什么不使用 react-router 提供的 <Redirect/> 组件?我认为这更清晰,更符合 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>
  }
}
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>;
        }
    }
}