在交换机内部使用Auth组件包装React路由器路由

时间:2018-01-20 14:51:44

标签: reactjs react-router-v4

我目前有一组路由,我希望只有在用户具有某个用户角色时才能访问这些路由,让我们说一个Admin角色。

我希望这些路由包含在一个组件中,比如说Auth,它将检查用户对所需角色的角色。

<Switch>
  <Auth roles={['user']}>
     <Route exact path="/repos/" component={Repos} />
     <Route exact path="/repos/:repo" component={Repo} />
  </Auth>
  <Auth roles={['admin']}>
     <Route exact path="/repos/:repo/settings" component={RepoSettings} />
  </Auth>
</Switch>

Auth就像这样,

const AuthWrapper = ({ children, roles, ...props }) => {
  if (Authenticator(roles)) {
    return React.Children.map(
        children,
        (child, i) => (React.cloneElement(child, {
            key: i, ...props,
        })),
    );
  }

  return null;
};

但问题是,当我转到ReposRepo时,/repos//repos/somerepo组件都会被渲染!

最后如何呈现它是这样的,

Finally how it is rendered is like this

这是一个带有我的代码的游乐场:https://codesandbox.io/s/oo7lzpww6q

1 个答案:

答案 0 :(得分:2)

更新回答:

使用Routes渲染React.cloneElement时,exact道具的值为true。这导致路由器错误匹配。如果您不需要为每个key添加Route道具,您应该可以通过简单地返回孩子来解决此问题。

原始回答:

根据docs

  

Switch的所有子节点都应该是Route或Redirect元素。

您可以创建一个包装路径的组件,获取角色prop并处理身份验证。

<PrivateRoute exact path='/repos/:repo/settings' roles={['admin']} component={RepoSettings} />

docs中有一个详细的例子。