user6488504
user6488504

Reputation:

react redux: private route not rendering layout

Code Sandbox link: Edit broken-worker-9xmm7

and trying to follow this article

On successful login(/auth/login), the user should be routed to the dashboard(/admin/summary). If the login is successful, I am also storing an access token.

I have a PrivateRoute component for this. The problem is that on successful login, the URL is getting updated but the component is not getting rendered.

PS: about the dashboard, this is a single page application so, the dashboard has topbar, sidebar, and the right content and altogether these things are coupled inside <AdminLayout/>. So, in my AppRouter, I have to render the <AdminLayout/> and just any one component.

All the react and redux code is included in the code sandbox.

Upvotes: 0

Views: 160

Answers (1)

OfirD
OfirD

Reputation: 10461

Since in your code you create your own history object (it happens in you history.js file, when you call createBrowserHistory()) but doesn't pass it to your Router, nothing happens.

There are 2 possible solutions:

1. Don't create a history object yourself, but use useHistory hook inside your component

Working Demo

With this approach, you should remove history.push from login.actions.js (which imports history) and use history.push in Login.js (which uses useHistory hook):

// login.actions.js
...
loginService.login(userid, password, rememberPassword).then(
    (userid) => {
      dispatch(success(userid, password, rememberPassword));
      // history.push(from); <-- commented out!
    },
    (error) => { ... }
  );
};
...

// Login.js

function handleSubmit(e) {
   ...
   const { from } = {
     from: { pathname: "/admin/summary" }
   };
   history.push(from) // <-- added!
   dispatch(loginActions.login(inputs, from));
   ...
}

useHistory exposes the history object of BrowserRouter (I think this is implied in this official blog post).

2. Create a history object yourself, but pass it to a Router component

Working Demo

This approach would require you to make several changes:

  1. Creating the history object on your own means you become responsible to provide it to a router component, but it can't be a BrowserRouter, but the base Router component (see these Github answers: 1, 2).

  2. Once you import Router (instead of BrowserRouter), you need to get rid of any useLocation and useHistory imports, otherwise you'll get errors.

  3. I also had to unify the history object export and imports, so that it is exported as the default export (i.e., export default history), and it is imported as the default import (i.e., import history from "./history"; instead of import { history } from "./history")

(P.S: this approach can be seen implemented elsewhere on SO, for example here or here (the latter explicitly installs history, but it's not needed in your case).

Upvotes: 0

Related Questions