【问题标题】:Redirection when typing in links manually, other issues with react-router props手动输入链接时的重定向,react-router props 的其他问题
【发布时间】:2018-04-24 09:13:21
【问题描述】:

我在我的应用程序中遇到了一个问题,当用户通过身份验证并手动输入他有权访问的所需链接地址时,页面会将他重定向到主页。仅单击链接时不会发生这种情况。

代码如下:

const asyncCheckout = asyncComponent(() => {
    return import('./containers/Checkout/Checkout');
});

const asyncOrders = asyncComponent(() => {
    return import('./containers/Orders/Orders');
});

const asyncAuth = asyncComponent(() => {
    return import('./containers/Auth/Auth');
});

class App extends Component {
    componentDidMount() {
        this.props.onTryAutoSignup();
    }

    render() {
        let routes = (
            <Switch>
                <Route path="/auth" component={asyncAuth} />
                <Route path="/" exact component={BurgerBuilder} />
                <Redirect to="/" />
            </Switch>
        );

        console.log('Is authenticated: ' + this.props.isAuthenticated);
        console.log(routes.props.children);


        if (this.props.isAuthenticated) {
            routes = (
                <Switch>
                    <Route path="/checkout" component={asyncCheckout} />
                    <Route path="/orders" component={asyncOrders} />
                    <Route path="/logout" component={Logout} />
                    <Route path="/auth" component={asyncAuth} />
                    <Route path="/" exact component={BurgerBuilder} />
                    <Redirect to="/" />
                </Switch>
            );

        }

        console.log('Is authenticated: ' + this.props.isAuthenticated);
        console.log(routes.props.children);

        return (
            <div>
                <Layout>
                    {routes}
                </Layout>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return {
        isAuthenticated: state.auth.token !== null
    };
};

const mapDispatchToProps = dispatch => {
    return {
        onTryAutoSignup: () => dispatch(actions.authCheckState())
    };
};

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(App));

以下是手动输入链接时 console.logs 显示的内容:

Is authenticated: false
App.js:38 Array(3)
App.js:55 Is authenticated: false
App.js:56 Array(3)
App.js:37 Is authenticated: true
App.js:38 Array(3)
App.js:55 Is authenticated: true
App.js:56 Array(6)

似乎是这样,因为当手动输入地址时,页面必须重新加载,这就是为什么用户一开始总是未经身份验证的原因。

我尝试弄乱 react-router 给我们的道具,以便以某种方式仍然成功地将用户重定向到正确的页面,但 this.props.match.urlthis.props.match.path 始终设置为“/”,即使点击在链接上。

所以我的两个问题是:

  1. 我应该如何处理重定向,当用户手动输入所需地址时,当他通过身份验证(令牌在 localStorage 中设置)?
  2. 我应该如何解决 react-router 的情况?

【问题讨论】:

    标签: javascript reactjs react-router react-redux


    【解决方案1】:

    实际上,您应该在应用程序的 init 上执行此操作。例如,在 index.js 文件中。

    像这样 - index.js 文件:

    ....
    const store = createStoreWithMiddleware(reducers);
    const token = localStorage.getItem('token');
    if (token) {
      store.dispatch(authCheckState());
    }
    ...
    

    因此,每次加载您的应用程序时,它都会检查当前用户的状态,并且您的容器将获得更新的信息。

    另外,我更喜欢使用授权 HoC 而不是覆盖路由。

    import React, {Component} from 'react';
    import {connect} from 'react-redux';
    import {Route, Redirect} from 'react-router-dom'
    
    export const PrivateRoute = ({component: ComposedComponent, ...rest}) => {
    
      class Authentication extends Component {
    
        /* Redirect if not authenticated; otherwise, return the component imputted into <PrivateRoute /> */
        handleRender = props => {
          if (!this.props.isAuthenticated) {
            return <Redirect to="auth" />
          } else {
            return <ComposedComponent {...props}/>
          }
        }
    
        render() {
          return (
            <Route {...rest} render={this.handleRender}/>
          );
        }
      }
    
      const mapStateToProps = state => {
        return {
          isAuthenticated: state.auth.token !== null
        };
      }
    
      const AuthenticationContainer = connect(mapStateToProps)(Authentication);
      return <AuthenticationContainer/>
    };
    

    然后在您的路由中,您可以使用此 HoC 在访问特定路由之前检查用户是否已登录:

    <Switch>
        <PrivateRoute path="/checkout" component={asyncCheckout}/>
        <PrivateRoute path="/orders" component={asyncOrders}/>
        <PrivateRoute path="/logout" component={Logout}/>
        <Route path="/auth" component={asyncAuth}/>
        <Route path="/" exact component={BurgerBuilder}/>
        <Redirect to="/" />
    </Switch>
    

    【讨论】:

      【解决方案2】:

      Reactjs 应用程序是客户端应用程序,即一旦下载了 JavaScript,客户端就会处理所有事情,甚至是地址栏中的地址。

      问题是服务器不知道这一点。但是,一旦你通过地址栏发送了一些东西,服务器就会认为有一些请求,它不知道该怎么做,因此它会返回 index.html 文件,这会触发主页的显示。

      首先,阅读这个答案React-router urls don't work when refreshing or writing manually

      这将为您提供有关如何处理此类情况的更多信息。

      第二件事是你应该在应用程序启动时检查用户是否经过身份验证,然后重定向他们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-05
        • 2019-06-28
        • 2023-03-21
        • 1970-01-01
        • 2020-07-17
        • 2021-11-12
        • 2018-12-09
        • 1970-01-01
        相关资源
        最近更新 更多