【问题标题】:Different component in a same React route based on roles基于角色的同一 React 路由中的不同组件
【发布时间】:2021-01-31 08:34:01
【问题描述】:

我想根据用户角色在同一个 React 路由上设置不同的组件。

这就是我所做的。

// AppRouter.js
const AppRouter = () => {

    const {loading, data, error}  = useQuery(GET_CURRENT_USER)

    if (loading) return <span>Loading...</span>
    if (error) return <Redirect to="/login"/>

    if (data) {
        let {me: {role}}= data

        if (role === 'user') {
            return (
                    <Switch>
                        <Route to="/" component={EmployeeHome}/>
                        <Route path="/login" exact component={SigninForm} />
                    </Switch>
            )
        } else {
            return (
                    <Switch>
                    <Route to="/" component={AdminHome}/>
                    <Route path="/login" exact component={SigninForm} />
                    </Switch>
            )
        }
    }

}

// App.js
    <Router history={history}>
      <div className="App">
        <header>
          <h3>This is header!</h3>
        </header>
        <Switch>
          <AppRouter />
          <Route path="/login" component={SigninForm} />
        </Switch>
      </div>
    </Router>

  1. 调用 graphql 查询,根据存储在 localStorage 中的授权令牌检索当前用户。
  2. 如果出错,将重定向到 /login
  3. 如果成功,将创建可用于该特定角色的特定路由。 3a。如果角色是用户,它将创建一个具有 EmployeeHome 组件的路由 3b。如果角色是管理员,它将创建一个具有 AdminHome 组件的路由

尝试上面的代码后,它没有加载指向/login路由的SigninForm。

应该做些什么来完成这项工作?

已添加:Replicable Codesandbox

【问题讨论】:

    标签: reactjs react-router


    【解决方案1】:

    没有必要在AppRouter 组件中使用Switch,除非它具有“嵌套”路由。此外,无需多次定义/login 路由。

    <Router history={history}>
      // ... header here
      <Switch>
        <Route exact path="/login" component={SigninForm} />
        <AppRouter />
      </Switch>
    </Router>
    

    AppRouter 在哪里:

    const AppRouter = () => {
      // define loading, error, role etc. 
    
      if (loading) return <span>Loading...</span>
      if (error) return <Redirect to="/login" />
    
      if (role === 'user') {
        return (
          <>
            <Route exact path="/" component={EmployeeHome} />
          </>
        )
      } else {
        return (
          <>
            <Route exact path="/" component={AdminHome} />
          </>
        )
      }
    }
    

    而且,&lt;Redirect to="/login" /&gt; 不应该是路由器设置的第一行,因为它会继续重定向到“/login”,而不会看到进一步定义的路由,因此不会呈现任何内容。当出现错误时,您在AppRouter 中的当前设置会返回&lt;Redirect to="/login" /&gt;,在这种情况下,它会成为有问题的第一行。

    不过,你可以这样写:&lt;Redirect exact from="/" to="/login" /&gt;

    【讨论】:

    • 我试过你上面的代码,直接访问“/login”路径时,组件渲染正确,但是当我尝试通过Redirect访问路径时,组件没有渲染。我也试过&lt;Redirect exact from="/" to="/login"/&gt;,但它没有渲染组件。
    • 更新代码后,控制台中记录了graphql身份验证失败消息(来自后端)。浏览器 url 也更改为“/login”。即使没有添加graphql服务器,如果此问题重复,我也会尝试制作一个codesandbox。
    • 我在帖子中添加了一个可复制的代码框。
    • 我认为是history 版本问题。因此,最好将其删除,因为 react-router-dom 会自动添加正确的版本。
    • 是的,我检查了最新的历史版本和 react-router-dom 版本有问题。
    猜你喜欢
    • 1970-01-01
    • 2017-07-17
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-06-12
    • 2012-01-01
    • 1970-01-01
    相关资源
    最近更新 更多