简体   繁体   English

react redux:私有路由不渲染布局

[英]react redux: private route not rendering layout

Code Sandbox link:代码沙盒链接: 编辑broken-worker-9xmm7

and trying to follow this article 并尝试关注这篇文章

On successful login(/auth/login) , the user should be routed to the dashboard(/admin/summary) .成功login(/auth/login) ,用户应该被路由到dashboard(/admin/summary) If the login is successful, I am also storing an access token .如果登录成功,我还存储了一个access token

I have a PrivateRoute component for this.为此,我有一个PrivateRoute组件。 The problem is that on successful login, the URL is getting updated but the component is not getting rendered.问题是,成功登录后,URL 会更新,但组件未呈现。

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/> . PS:关于仪表板,这是一个单页应用程序,仪表板有顶栏、侧边栏和正确的内容,这些东西一起耦合在<AdminLayout/> So, in my AppRouter , I have to render the <AdminLayout/> and just any one component.因此,在我的AppRouter ,我必须呈现<AdminLayout/>和任何一个组件。

All the react and redux code is included in the code sandbox.所有 react 和 redux 代码都包含在代码沙箱中。

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.由于在您的代码中您创建了自己的history对象(它发生在您的history.js文件中,当您调用createBrowserHistory() )但没有将其传递给您的Router ,没有任何反应。

There are 2 possible solutions:有两种可能的解决方案:

1. Don't create a history object yourself, but use useHistory hook inside your component 1. 不要自己创建history对象,而是在组件内部使用useHistory钩子

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 (导入history )中删除history.push并在Login.js (使用useHistory钩子)中使用history.push

// 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 ). useHistory暴露history的对象BrowserRouter (我认为这是在暗示这个官方博客文章)。

2. Create a history object yourself, but pass it to a Router component 2.自己创建一个history对象,但是传递给Router组件

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 ).自己创建history对象意味着您有责任将它提供给路由器组件,但它不能是BrowserRouter ,而是基本Router组件(请参阅这些 Github 答案: 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.一旦你导入Router (而不是BrowserRouter ),你需要去掉任何useLocationuseHistory导入,否则你会得到错误。

  3. I also had to unify the history object export and imports, so that it is exported as the default export (ie, export default history ), and it is imported as the default import (ie, import history from "./history"; instead of import { history } from "./history" )我还得统一history对象的export和imports,让它作为默认export导出(即export default history ),作为默认import导入(即import history from "./history";而不是import { history } from "./history" )

(PS: 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). (PS:这种方法可以在SO的其他地方看到,例如herehere (后者明确安装history ,但在您的情况下不需要)。

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

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