<开关>react-router-4 中的组件匹配空值 [英] <Switch> component matching null value in react-router-4

查看:38
本文介绍了<开关>react-router-4 中的组件匹配空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试迁移以使用 React Router 4,但在理解 <Switch> 组件的逻辑时遇到了一些麻烦,因为它在 docs 处理 404(或不匹配)路由.

I'm trying to migrate to use React Router 4 and having some trouble understanding the logic of the <Switch> component as it's used in the docs to handle a 404 (or unmatched) route.

对于我的入口 JavaScript 文件,我设置了以下路由.

For my entry JavaScript file, I have the following routes set up.

index.js

<Switch>
    <Route path="/login" component={Login} />
    <Route path="/forgot-password" component={ForgotPassword} />
    <Route path="/email-verification" component={EmailVerification} />
    <Route component={App} />
</Switch>

Login 组件将检查用户是否通过身份验证,如果通过,将用户重定向到 /dashboard 路由(通过 history.replace).

The Login component will check to see if the user is authenticated, and if so, redirect the user to the /dashboard route (via history.replace).

App 组件仅在用户通过身份验证时才可访问,如果用户未通过身份验证,它会进行类似的检查以将用户重定向到 /login.

The App component is only accessible when the user is authenticated and it has a similar check to redirect the user to /login if she is not.

在我的 App 组件中,我有更多指定的路由,我可以确定只有在用户登录时才能访问这些路由.

In my App component I have more specified routes that I can be sure are only accessible if the user is logged in.

App.js

<Switch>
    <Route path="/dashboard" component={Dashboard} />
    <Route path="/accounts" component={Account} />
    <Authorize permissions={['view-admin']}>
        <Route path="/admin" component={Admin} />
    </Authorize>
    <Route path="/users" component={Users} />
    <Route component={NotFound} />
</Switch>

这就是我的问题.Authorize 组件检查传递的权限以查看用户是否具有这些权限,如果有,则直接呈现子级,如果没有,它从 render() 返回 null.

Herein lies my problem. The Authorize component checks against the permissions passed to see if the user has those permissions, if so, it renders the children directly, if not, it returns null from render().

此处的预期行为是 <Route path="/admin"/> 在权限不足且 <Route 组件={NotFound}/> 组件呈现.

The expected behavior here is that the <Route path="/admin" /> does not render at all when there are insufficient permissions and the <Route component={NotFound} /> component renders.

根据文档:

A 呈现第一个匹配的孩子.一种没有路径总是匹配.

A renders the first child that matches. A with no path always matches.

但是,如果我转到在 组件之后声明 的任何路由,路由器将匹配 null.这意味着,根据上面的示例,转到 /users 会返回 null.react-router 的预期行为是否会返回 <Switch/> 组件中的第一个匹配项,即使它是一个 null 值?

However, if I go to any route declared after the <Authorize> component, the router is matching to null. This means that, based on the example above, going to /users returns null. Is the expected behavior of react-router to return the first match in a <Switch/> component, even if it's a null value?

如何在不为 App 中许多经过身份验证的路由中的每一个创建 组件的情况下为这种情况提供全能"路由 (404)?js?null 值真的应该产生匹配吗?

How can I provide a "catch-all" route (404) for such a situation without creating a <PrivateRoute> component for each of the many, authenticated routes in App.js? Should a null value really produce a match?

推荐答案

不幸的是,react-router 的 Switch 组件不适用于嵌套在其他组件中的路由,例如您的示例.如果您查看 Switch 的文档,它会说:

Unfortunately, react-router's Switch component won't work with routes nested inside other components like in your example. If you check the docs for Switch, it says:

的所有子级应该是<Route>或<重定向>元素.

All children of a <Switch> should be <Route> or <Redirect> elements.

...所以你的 Authorize 组件作为 Switch 的直接子元素实际上并不合法.

... so your Authorize component is not actually legal there as a direct child of Switch.

如果您阅读了 Switch 组件的源代码,你会看到它相当邪恶地读取每个子组件的 props 并在每个子组件的 上手动应用 react-router 的 matchPath 方法path(或 from)prop 来决定应该渲染哪一个.

If you have a read through the source code of the Switch component, you'll see that it rather evilly reads the props of each of its children and manually applies react-router's matchPath method on each child's path (or from) prop to determine which one should be rendered.

因此,在您的情况下发生的是 Switch 遍历其子项,直到它到达您的 Authorize 组件.然后查看该组件的 props,找不到 pathfrom prop,并在未定义的路径上调用 matchPath.正如您自己指出的那样,没有路径的 <Route> 总是匹配",因此 matchPath 返回 true,并且 Switch 呈现您的 Authorize 组件(忽略任何后续的路由或重定向,因为它相信它找到了匹配项).但是,Authorize 组件中嵌套的/admin"路由与当前路径不匹配,因此您会从渲染中获得空结果.

So, what's happening in your case is Switch iterates through its children until it gets to your Authorize component. It then looks at that component's props, finding neither a path or from prop, and calls matchPath on an undefined path. As you note yourself, "a <Route> with no path always matches", so matchPath returns true, and Switch renders your Authorize component (ignoring any subsequent Routes or Redirects, since it believes it found a match). The nested '/admin' route inside your Authorize component doesn't match the current path however, so you get a null result back from the render.

我在工作中遇到了类似的情况.我解决这个问题的计划是用一个自定义组件替换路由代码中 react-router 的 Switch ,该组件遍历其子组件,依次手动渲染每个组件,并返回第一个返回 null 以外的内容.当我试一试时,我会更新这个答案.

I'm facing a similar situation at work. My plan to work around it is to replace react-router's Switch in my routing code with a custom component which iterates through its children, manually rendering each one in turn, and returning the result of the first one that returns something other than null. I'll update this answer when I've given it a shot.

好吧,那没用.我无法找到一种受支持的方法来手动调用孩子的渲染".抱歉,我无法为您提供解决 Switch 限制的方法.

Well, that didn't work. I couldn't work out a supported way to manually invoke "render" on the children. Sorry I couldn't give you a workaround to Switch's limitations.

这篇关于&lt;开关&gt;react-router-4 中的组件匹配空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆