几秒钟后自动从一个组件重定向到另一个组件 - 反应
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>;
}
}
}
我尝试在几秒钟后将用户从一个组件重定向到另一个组件。
用户登陆一个页面,几秒钟后他自动重定向到另一个页面。 我想在一个动作中重定向,但我不确定这是否是最好的主意(如果你有更简单的方法,我很感兴趣)。
到目前为止我的代码:
一个基本组件:
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>;
}
}
}