【发布时间】:2023-04-11 03:34:01
【问题描述】:
您好,我正在构建一个使用 reactjs redux 和 react-router-dom 的项目。
由于一些我无法弄清楚的奇怪原因,当我导航到 http://localhost:3000 时,我收到以下错误:
Warning: You tried to redirect to the same route you're currently on: "/signin"
我从类似的问题中尝试了很多东西,但没有运气。也许Switch 不起作用?或者我需要一双新鲜的眼睛,因为这可能很明显......
下面是我的源代码:
router.jsx
import React from 'react';
import { connect } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import Routes from '../routes/index.jsx';
// Global Components
import CustomNavbar from '../navbar/index.jsx';
import Sidemenu from '../sidemenu/index.jsx';
import Emulator from '../emulator/index.jsx';
// Styles
import 'font-awesome/css/font-awesome.css';
import 'bootstrap/dist/css/bootstrap.css';
import '../../sass/style.scss';
import '../../sass/router.scss';
class CustomRouter extends React.Component {
constructor(props) {
super(props);
}
isSignedin = () => {
return this.props.user.authenticated;
}
isSidemenuOpen = () => {
return this.props.app.sidemenu.open;
}
isEmulatorOpen = () => {
return this.props.app.emulator.open;
}
getWrapperClassName = () => {
let classList = [];
if (this.isSignedin()) {
classList.push('authenticated');
}
if (this.isSidemenuOpen()) {
classList.push('sidemenu');
}
if (this.isEmulatorOpen()) {
classList.push('emulator');
}
return classList.join(' ');
}
render = () => {
return (
<BrowserRouter>
<div id='wrapper' className={this.getWrapperClassName()}>
{(() => {
if (this.isSignedin()) {
return (
<React.Fragment>
<Sidemenu />
<CustomNavbar />
<Emulator />
</React.Fragment>
)
} else {
return null;
}
})()}
<div id='page-content'>
<div className='p-4'>
<Routes />
</div>
</div>
</div>
</BrowserRouter>
)
}
}
const mapStateToProps = (state) => {
return {
app: state.appReducer,
user: state.userReducer
}
}
export default connect(mapStateToProps, null, null, { withRef: true })(CustomRouter);
routes.jsx
import React from 'react';
import { withRouter, Switch, Route } from 'react-router-dom';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import AuthenticatedRoute from '../authenticatedRoute/index.jsx';
import UnauthenticatedRoute from '../unauthenticatedRoute/index.jsx';
// Root Components
import Home from '../routes/home/index.jsx';
import Dashboard from '../routes/dashboard/index.jsx';
import Bots from '../routes/bots/index.jsx';
import Actions from '../routes/actions/index.jsx';
import Flows from '../routes/flows/index.jsx';
import Sessions from '../routes/sessions/index.jsx';
import Users from '../routes/users/index.jsx';
import Signin from '../routes/signin/index.jsx';
import Signup from '../routes/signup/index.jsx';
import Reset from '../routes/reset/index.jsx';
import NotFound from '../routes/notfound/index.jsx';
const Routes = ({ location }) => {
return (
<TransitionGroup className='transition-group'>
<CSSTransition key={location.key} classNames='fade' timeout={{ enter: 300, exit: 300 }}>
<section className='route-group'>
<Switch location={location} >
<Route path='/' component={Home} exact={true}></Route>
<UnauthenticatedRoute path='/signin' component={Signin} exact={true}></UnauthenticatedRoute>
<UnauthenticatedRoute path='/signup' component={Signup} exact={true}></UnauthenticatedRoute>
<UnauthenticatedRoute path='/reset' component={Reset} exact={true}></UnauthenticatedRoute>
{/* <AuthenticatedRoute path='/dashboard' component={Dashboard} exact={true}></AuthenticatedRoute>
<AuthenticatedRoute path='/bots/:botId?' component={Bots} exact={true}></AuthenticatedRoute>
<AuthenticatedRoute path='/actions/:actionId?' component={Actions} exact={true}></AuthenticatedRoute>
<AuthenticatedRoute path='/flows/:flowId?' component={Flows} exact={true}></AuthenticatedRoute>
<AuthenticatedRoute path='/users/:userId?' component={Users} exact={true}></AuthenticatedRoute>
<AuthenticatedRoute path='/sessions/:sessionId?' component={Sessions} exact={true}></AuthenticatedRoute> */}
<Route path='*' component={NotFound}></Route>
</Switch>
</section>
</CSSTransition>
</TransitionGroup>
)
}
export default withRouter(Routes);
home.jsx(/虚拟路由组件)
它仅用于将您重定向到 /dashboard 或 /signin 相应地
import React from 'react';
import { connect } from 'react-redux';
import { Redirect } from "react-router-dom";
import '../../../sass/home.scss';
class Home extends React.Component {
constructor(props) {
super(props);
this.state = this.getInitialState();
}
getInitialState = () => {
return {};
}
render = () => {
let { authenticated } = this.props.user;
if (authenticated) {
console.log('Redirecting to "/dashboard" from home');
return (
<Redirect to="/dashboard" />
)
} else {
console.log('Redirecting to "/signin" from home');
return (
<Redirect to="/signin" />
)
}
}
}
const mapStateToProps = (state) => {
return {
app: state.appReducer,
user: state.userReducer
}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
export default connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(Home);
unauthenticated.jsx
(对于仅在未经过身份验证时才可访问的路由)
import React from 'react';
import { connect } from 'react-redux';
import { Route, Redirect, withRouter } from 'react-router-dom';
class UnauthenticatedRoute extends React.Component {
constructor(props) {
super(props);
}
isSignedin = () => {
return this.props.user.authenticated;
}
render = () => {
let { component: Component, ...rest } = this.props;
console.log('Unauthenticated:', !this.isSignedin() ? `Rendering` : `Redirecting`);
return (
<Route {...rest} render={(props) => (
!this.isSignedin() ? (
<Component {...props} />
) : (
<Redirect to='/dashboard' />
)
)} />
)
}
}
const mapStateToProps = (state) => {
return {
app: state.appReducer,
user: state.userReducer
}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(UnauthenticatedRoute));
authenticated.jsx
(对于只有经过身份验证才能访问的路由)
import React from 'react';
import { connect } from 'react-redux';
import { Route, Redirect, withRouter } from 'react-router-dom';
class AuthenticatedRoute extends React.Component {
constructor(props) {
super(props);
}
isSignedin = () => {
return this.props.user.authenticated;
}
render = () => {
let { component: Component, ...rest } = this.props;
console.log('Authenticated:', this.isSignedin() ? `Rendering` : `Redirecting`);
return (
<Route {...rest} render={(props) => (
this.isSignedin() ? (
<Component {...props} />
) : (
<Redirect to='/signin' />
)
)} />
)
}
}
const mapStateToProps = (state) => {
return {
app: state.appReducer,
user: state.userReducer
}
}
const mapDispatchToProps = (dispatch) => {
return {}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps, null, { withRef: true })(AuthenticatedRoute));
【问题讨论】:
-
PS:只有当我导航到“/”时才会出现问题。如果我导航到 /signin,则没有控制台错误。
-
您确定没有将Authenticated和Unauthenticated的组件命名错误。请检查源代码和名称。如果可以,请告诉日志(console.logs),它会出现。
-
唯一使用这两个的地方是在 routes.jsx 中。名称似乎没问题,因为唯一未经身份验证的路线是登录注册和重置。 '/' 路由是一个简单的路由组件。日志将描述中提到的错误打印 5 次
-
还没有完成这方面的逻辑,但是如果
isSignedIn()在嵌套子级render()s 中调用总是失败,因为它不一定要更正this上下文?将this.isSignedIn = this.isSignedIn.bind(this)添加到适当的构造函数有帮助吗? -
它没有失败,因为它被声明为箭头函数,并且最新的 babel transpile 保留了上下文,因此您不需要再绑定 @AndyTaton
标签: reactjs redux react-router-v4 react-router-dom