0

I realized this has been asked before, please bear with me since I am still learning this. And I think I've tried all solutions in SO but without luck.

The issue is: When PrivateRoute redirects to /sign_in, it's not rendering the expected component (SignInForm)

I have implemented a PrivateRoute as following;

PrivateRoute.js

import React, { Component } from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { Route, Redirect, withRouter } from "react-router-dom";

// Simplified and still can reproduce the issue;
class PrivateRoute extends Route {
  render () {
    return (<Redirect to="/sign_in" />);
  }
}

PrivateRoute.propTypes = {
  isAuthenticated: PropTypes.bool.isRequired,
};

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

export default withRouter(connect(mapStateToProps)(PrivateRoute));

And this is where I use it;

index.js

<div className="content position-relative">
    <div className="content-container font-nunito">
        <Switch>
            <Route path="/sign_in" component={SignInForm} />
            <Route exact path="/" component={LandingPage} />
            <PrivateRoute path="/trips" component={TestPage} />
        </Switch>
    </div>
</div>

Few points to add into the question:

  1. I confirm that Redirection does happen in PrivateRoute (I tested this by changing the to param to another route, and I see the URI changes in my browser).
  2. If I go directly to /sign_in, it works fine. The only problem is only when <Redirect> does it.
  3. My last resort will be to hackishly doing native browser redirect if this can not be solved. But, I'd like to avoid this if possible.

Here are my previous attempts that I have tried;

  1. Using withRouter in my PrivateRoute - based on this answer
  2. Sets the PrivateRoute not to be pure - based on this answer
  3. Tried importing Redirect and withRouter from react-router instead of react-router-dom
  4. Installed path-to-regexp@^2.4.0
  5. Use push in Redirect - Based on this answer

I am currently using react-router-dom@5.2.0 and react@^16.2.0.

Please help, any suggestions is appreciated. Let me know if I can provide more details.

choz
  • 14,911
  • 3
  • 42
  • 65
  • What happens if you remove or change its `component` directive: ``? – GAEfan Jul 22 '20 at 16:21
  • Hi @GAEfan - It seems like any components will fail to render there. I changed it to `NotFound` just now to ensure it and it still doesn't behave correctly. I don't think the problem lies there since the fact that if I go directly to `/sign_in` it works just fine. – choz Jul 22 '20 at 16:24

1 Answers1

0

Edit: I've found the real issue, it seems like all the routes need to be wrapped inside BrowserRouter. So here's my final solution;

<BrowserRouter>
    <div className="content position-relative">
        <div className="content-container font-nunito">
            <Switch>
                <Route path="/sign_in" component={SignInForm} />
                <Route exact path="/" component={LandingPage} />
                <PrivateRoute path="/trips" component={TestPage} />
            </Switch>
        </div>
    </div>
</BrowserRouter>

Old:

I solved it by downgrading react-router-dom from 5.2.0 to 4.3.1.

This seems to fix the issue with a bit of side-effect this issue

So my final changes is;

package.json

- "react-router-dom": "^5.2.0",
+ "react-router-dom": "^4.3.1",

index.js (To avoid the side effect)

<Switch>
    <Route exact path="/" component={props => <LandingPage {...props} />} />
    <Route path="/sign_in" component={props => <SignInForm {...props} />} />

    <PrivateRoute path="/trips" component={props => <TestPage {...props} />} />
</Switch>
choz
  • 14,911
  • 3
  • 42
  • 65