使用片段后,重定向在Switch内部不起作用

时间:2019-09-30 13:54:53

标签: javascript reactjs react-router

版本

"react-router": "5.0.1",

测试用例

<Switch>
    <Route
        component={TestComponent}
        key={TestComponentPath}
        path={TestComponentPath}
        exact
    />
    {
        exampleCondition && (
            <>
                 <Route
                    component={TestComponent2}
                    key={TestComponentPath2}
                    path={TestComponentPath2}
                    exact
                 />
                 <Route
                    component={TestComponent3}
                    key={TestComponentPath3}
                    path={TestComponentPath3}
                    exact
                 />
            </>
        )
    }
    <Redirect to={redirectUrl} />
</Switch>

复制步骤

显示的示例SwitchRedirect用例。

预期行为

如果没有匹配的路径,应重定向到给定的redirectUrl路径。

实际行为

就像在切换结束时没有提供Redirect一样。问题可能是由React.Fragment内部使用的Switch引起的。重定向删除后可以正常工作。

沙箱示例

https://codesandbox.io/s/react-router-tklng

2 个答案:

答案 0 :(得分:1)

  

<Switch>的所有子代应为<Route><Redirect>元素。   将仅显示与当前位置匹配的第一个孩子。

https://reacttraining.com/react-router/web/api/Switch/children-node

由于使用的是Fragment,因此要添加Switch不支持的其他子项,因此代码不会呈现。

您应按以下方式切换代码,以添加条件路由而不使用片段:

<Switch>
    <Route
        component={TestComponent}
        key={TestComponentPath}
        path={TestComponentPath}
        exact
    />
    { exampleCondition &&
                 <Route
                    component={TestComponent2}
                    key={TestComponentPath2}
                    path={TestComponentPath2}
                    exact
                 /> }
    { exampleCondition &&
                  <Route
                    component={TestComponent3}
                    key={TestComponentPath3}
                    path={TestComponentPath3}
                    exact
                 /> }
    <Redirect to={redirectUrl} />
</Switch>

如果您担心重复代码,可以在Route中添加如下所示的附加层:

<Switch>
    <Route
        component={TestComponent}
        key={TestComponentPath}
        path={TestComponentPath}
        exact
    />
   {someCondition && [
            <Route
              component={TestComponent2}
              key={TestComponentPath2}
              path={TestComponentPath2}
              exact
            />,
            <Route
              component={TestComponent3}
              key={TestComponentPath3}
              path={TestComponentPath3}
              exact
            />
    ]}
    <Redirect to={redirectUrl} />
</Switch>

答案 1 :(得分:0)

我喜欢 <ProtectedRoute> 组件的想法:

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

class ProtectedRoute extends Component<any> {
  render() {
    const { component: Component, allow, ...props } = this.props;
    if (!allow) {
      return <Redirect to={{ pathname: '/signin' }} />;
    }
    return <Route {...props} render={(props) => <Component {...props} />} />;
  }
}

export default ProtectedRoute;

然后像下面这样使用它:

<Router history={history}>
  <Route path={yourRootPath} component={App} exact>
    <Route path="home" component={Home} />
    <Route path="about" component={About} />

    <ProtectedRoute path="inbox" component={Inbox} allow={this.props.mail} />
    <ProtectedRoute path="contacts" component={Contacts} allow={this.props.mail} />

  </Route>
</Router>

<块引用>

我尝试按照公认的答案使用数组,但没有用 因为JSX 表达式必须有一个父元素(也许这个 曾经在较旧的 React 版本中工作),我也不想重复 代码。