在React Router应用中获取所有组件/路由的登录/注销信息

时间:2018-08-17 12:48:30

标签: reactjs react-router

我有一个民意测验应用程序,允许用户创建民意测验并对其进行投票。它还具有登录功能。问题是我正在处理<Top>组件(Reactstrap <Navbar>)中的登录,并且某些组件的内容取决于是否有人登录。例如,如果某人未登录并使用/polls/:pollnumber网址,然后登录,则我需要更新<Poll>中的内容(例如,允许他们对民意调查投票,而不是只是看到结果)。我不知道如何构建我的应用程序以使其正常工作。

这是我的主浏览器路由器页面

/* app.jsx */

const local = localStorage.getItem('poll-login');

if (local) {
  let info = JSON.parse(local);
  let loggedIn = true;
  let name = info.name;
  let token = info.token;
  let twitter_id = info.twitter_id;
};

ReactDOM.render((
  <BrowserRouter>
    <div>
      <Top loggedIn={ loggedIn } name={ name } token={ token } />
      <Route exact path="/" component={ HelloWorld } />
      <Route exact path="/newpoll" component={ Newpoll } loggedIn={ loggedIn } name={ name } token={ token } />
      <Route exact path="/polls/:pollnumber" component={ Poll } loggedIn={ loggedIn } name={ name } token={ token } />
    </div>
  </BrowserRouter>), document.getElementById('main'));

首次加载应用程序时,我检查localStorage以查看是否有人以前登录过,并将该信息传递给两个子组件。 <Top>是一个导航栏,并具有Twitter身份验证策略作为其导航项之一,导航栏将根据该人是否已登录(如我所愿)而更改。

如您所见,导航栏(<Top>)呈现在每个视图上。但是,如果用户未登录且位于/newpoll/polls/:pollnumber之类的路径上,然后用户登录,则<Top>组件的状态将更改(如我所愿),但不会更改其他的,我希望根据用户是否登录来确定它们的呈现方式。

我在其他组件中尝试过ComponentDidUpdate,但是在<Top>组件上发生登录/注销时,它不会触发。

我是React-Router的新手,但我的理解是在主state文件中没有<BrowserRouter>,所以我的理解是我无法在那里处理登录并传递状态更改(例如登录名)到子组件。如何构造我的应用程序,以便这些兄弟组件/路由能够获取登录/注销信息,以便根据需要呈现它们?

1 个答案:

答案 0 :(得分:2)

对于您来说,当您在路径/newpoll上登录时,没有路由更改,这就是为什么不会触发路由更新的原因。 现在,您可以选择使用哪种实现:

  • 创建一个PrivatePage和PublicPage组件,并在用户登录或注销时显示它们。这样,PrivatePage子项将重新安装
  • 那里没有状态,但是您可以创建一个状态,只需渲染一个将保留auth状态并通过操作(redux等)控制它的组件即可。
  • 您甚至可以将所有Route作为子元素放在Top组件中,并仅在用户验证后显示它们。
  • 我个人喜欢为授权路线做包装,如下所示:

privateroute.js:

import React from 'react';
import { Route, Redirect } from 'react-router-dom';

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        localStorage.getItem('user')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} 
/>
    )} />
)