首次登录后反应不重定向。但是在强制重定向并再次执行登录操作后重定向

React not redirecting after first login. But redirects after forcefully redirecting and doing a login action again

我有一个登录表单,点击它会调用以下函数。

总结,从 api 获取响应,如果有效,设置 cookie,然后使用 this.props.history.push()

重定向
handleSubmit(event) {
    event.preventDefault();
    const { email, password } = this.state;
    axios({
        method: 'post',
        url: 'http://localhost:3003/login',
        data: qs.stringify({ email, password }),
        headers: {
            'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
        }
    }).then(res => {
        console.log("set cookie")
        //the accestoken is set as a cookie in order to check routes
        Cookies.set('accesstoken', res.data.accesstoken);
        console.log("those are the props")
        console.log(this.props);

        this.props.history.push('/'); //the bug


    }).catch(err => {
        console.log(err)
    })  


}

但我面临的问题是,当我第一次登录时,重定向不起作用。它设置了所有的 cookie 和所有这些,但它从未真正将用户重定向到所需的目录。所以我被迫通过在浏览器搜索栏中输入我想要的路线来重定向自己。

这意味着一旦我强迫自己进入所需的目录,如果我注销(基本上删除 cookie),然后尝试再次登录。这次重定向成功了。

在我使用 ctrl+F5 清除所有缓存之前它会一直工作,这恰好导致了我在第一次登录时遇到的同样问题,所以我不得不再次手动重定向。

编辑:这是我的路线的样子

<BrowserRouter>
                <Switch>

                    <Route exact path="/login" render={(props) => <LoginPage {...props}/>} />

                    <PrivateRoute authed={this.state.isAuthenticated} exact path="/" render={(props) => <RegisterPage />} />

                </Switch>
            </BrowserRouter>

这些是我的私人路线

import { Route } from 'react-router-dom';

从 'react' 导入 React; 从 'react-router';

导入 { 重定向}
export default ({ component: Component, render: renderFn, authed,  ...rest }) =>{
  //The privateroute is fed with the auth state of app.js and evaluates the render based on that . If flase always renders "/"
  if (Component){
    return (
      <Route
      {...rest}
      render={props =>
        authed === true ? (
          <Component {...props} />
        ) : (
            <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
          )
      }
    />
    )
  } else {
    return ( //Second case is for iframe based renders
      <Route {...rest} render={props => authed === true ? renderFn(props) : <Redirect to={{ pathname: '/login', state: { from: props.location } }} /> } /> 
      );
  }
}

编辑 2:

app.js

    constructor(props) {
        super(props);

        console.log("PROPS APPJS")
        console.log(props)

        //checks if user is autheticated within the system in order to manage routes
        this.state = {
            authenticationChecked: false,
            isAuthenticated: false 

        }  



    }


    componentDidMount() {
        //calls the auth service to decide the auth state value
        isAuthenticated().then((result) => {
            if (result === true) {
                this.setState({ isAuthenticated: true, authenticationChecked: true})
            } else {
                this.setState({ isAuthenticated: false, authenticationChecked: true})
            }
        });
    }

    login = (email, password) => {
        var thiscomponent  = this;
        axios({
            method: 'post',
            url: 'http://localhost:3003/login',
            data: qs.stringify({ email, password }),
            headers: {
                'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
            }
        }).then(res => {
            console.log("set cookie")
            //the accestoken is set as a cookie in order to check routes
            Cookies.set('accesstoken', res.data.accesstoken);
            console.log("those are the props")
            console.log(this.props);
            this.setState({ isAuthenticated: true }, () => {
               thiscomponent.props.history.push('/'); //the bug
            })

        }).catch(err => {
            console.log(err)
        })  
    }

.
.
.
.
.
.
.
<BrowserRouter>
                <Switch>

                    <PrivateRoute authed={this.state.isAuthenticated} exact path="/" render={(props) => <NewLandingPage login={this.login} {...props} exact />} />
                </Switch>
            </BrowserRouter>

登录页面

 handleSubmit(event) {
        const { email, password } = this.state;
        this.props.login(email, password)
        event.preventDefault();


    }

编辑:登录页面道具

  {"history":{"length":15,"action":"POP","location":{"pathname":"/login","search":"?email=test4%40test.com&password=test","hash":""}},"location":{"pathname":"/login","search":"?email=test4%40test.com&password=test","hash":""},"match":{"path":"/login","url":"/login","isExact":true,"params":{}}}

您在何时何地设置 isAuthenticated? – lehm.ro 7 分钟前
@lehm.ro 在我的 app.js 中,在 componentDidMount() 期间,默认 isAuthenticated 是 false – mouchin777 6 分钟前 然后一旦你重定向你必须使用 this.setState 来使它成为真的,否则你的私人路线将不会显示。但是为此你需要将真实状态传递到 app.js 然后触发一个函数来为 isAuthenticated true 设置状态,然后重定向到该路由

设置您的历史记录以在 app.js 中工作而不被 props 传递:

In order to make use of history in the App component use it with withRouter. You need to make use of withRouter only when your component is not receiving the Router props,

This may happen in cases when your component is a nested child of a component rendered by the Router or you haven't passed the Router props to it or when the component is not linked to the Router at all and is rendered as a separate component from the Routes.

import React from 'react';
import { Route , withRouter} from 'react-router-dom';
import Dashboard from './Dashboard';
import Bldgs from './Bldgs';

var selectedTab;

class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    selectedTab = 0;
  }

  handleClick(value) {
    selectedTab = value;
    // console.log(selectedTab);
    this.props.history.push('/Bldgs');
    // console.log(this.props);
  }

  render() {
    var _this = this;

    return (
      <div>
        <Route exact path="/" render={(props) => <Dashboard {...props} handleClick={_this.handleClick} />} />
        <Route path="/Bldgs" component={Bldgs} curTab={selectedTab} />
      </div>
    );
  }
}

export default withRouter(App);

[Documentation][1] on withRouter

[1]: https://reacttraining.com/react-router/web/api/withRouter

变化 App.js

<Route exact path="/login" render={(props) => <LoginPage login={this.login} {...props}   />} />

并添加

login = (email, password) => {
    var thiscomponent = this;
    axios({
        method: 'post',
        url: 'http://localhost:3003/login',
        data: qs.stringify({ email, password }),
        headers: {
            'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
        }
    }).then(res => {
        console.log("set cookie")
        //the accestoken is set as a cookie in order to check routes
        Cookies.set('accesstoken', res.data.accesstoken);
        console.log("those are the props")
        console.log(this.props);
        this.setState({ isAuthenticated: true }, () => {
           thiscomponent.props.history.push('/'); //the bug
        })

    }).catch(err => {
        console.log(err)
    })  
}

并在登录页面

handleSubmit(event) {
    const { email, password } = this.state;
    this.props.login(email, password)
    event.preventDefault();
}