简体   繁体   English

手动输入链接时重定向,其他问题与react-router道具有关

[英]Redirection when typing in links manually, other issues with react-router props

I'm facing an issue in my app, when the user is authenticated and he types in the desired link address manually, which he has access to, the page redirects him to the home page. 我的应用程序遇到问题,当用户通过身份验证并手动输入所需的链接地址(可以访问)时,该页面会将他重定向到首页。 This doesn't happen when simply clicking on the links. 只需单击链接,就不会发生这种情况。

Here is the code: 这是代码:

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));

Here is what the console.logs show, when manually typing in the links: 手动输入链接时,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)

It seems like it does this, because when manually typing in addresses, the page has to reload, and that's why user will always be unauthenticated at first. 似乎是这样做的,因为当手动输入地址时,必须重新加载页面,这就是为什么用户一开始总是未经身份验证的原因。

I tried messing with the props that the react-router giveds us in order to somehow still successfully redirect the user to the correct page, but the this.props.match.url and this.props.match.path is always set to "/", even when clicking on links. 我尝试弄乱react-router提供给我们的道具,以某种方式仍然可以成功地将用户重定向到正确的页面,但是this.props.match.urlthis.props.match.path始终设置为“ / ”,即使单击链接也是如此。

So my two questions are: 所以我的两个问题是:

  1. How should I handle the redirection, when the user manually types in the desired address, when he is authenticated (token is set in localStorage)? 当用户手动输入所需的地址,通过身份验证(令牌在localStorage中设置)时,我应该如何处理重定向?
  2. How should I fix the react-router situation? 我应该如何解决反应路由器的情况?

Actually, you should perform this action on init of your application. 实际上,您应该在应用程序的初始化上执行此操作。 For instance, in index.js file. 例如,在index.js文件中。

Like this - index.js file: 像这样index.js文件:

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

So every time when your application is loaded it will check status of current user and your containers will get updated information. 因此,每次加载您的应用程序时,它将检查当前用户的状态,并且您的容器将获取更新的信息。

Also, I prefer to use authorization HoC instead of overriding routes. 另外,我更喜欢使用授权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/>
};

And then in your routes you can just use this HoC to check if user is logged in before it will access to the particular route: 然后在您的路由中,您可以使用此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>

Reactjs apps are client side apps, ie, once the JavaScript is downloaded, the client handles everything, even the address in the address bar. Reactjs应用程序是客户端应用程序,即,一旦下载了JavaScript,客户端就可以处理所有内容,甚至包括地址栏中的地址。

The thing is the server doesn't know about this. 问题是服务器对此一无所知。 But, once u send something through address bar, the server thinks that some request is made, it doest know what to do, hence it sends the index.html file back, which triggers showing of homepage. 但是,一旦您通过地址栏发送了一些内容,服务器就会认为已经发出了一些请求,它不知道该怎么做,因此它会将index.html文件发回,从而触发了首页的显示。

First thing, read this answer React-router urls don't work when refreshing or writing manually 首先,请阅读此答案手动刷新或编写时,React-router网址不起作用

This will give you more info about how to handle such situations. 这将为您提供有关如何处理此类情况的更多信息。

Second thing is that u should check whether a user is authenticated or not at the start of the app, and then redirect them. 第二件事是,您应在应用程序启动时检查用户是否已通过身份验证,然后将其重定向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM