【问题标题】:react-router redirect doesn't change url in Switchreact-router 重定向不会更改 Switch 中的 url
【发布时间】:2019-12-29 07:09:27
【问题描述】:

我正在使用 react-router 设置我的应用程序,并尝试使用<Redirect/> 设置路由器进行身份验证。

Routecomponent 有两个不同的组件,一个是private Route,另一个是public route

预期结果:当 auth 为 false 时,页面应该跳转回我设置的公共页面 <Redirect to={"/public"} /> 到目前为止,似乎路由工作正常,但重定向不能正常工作。 欢迎任何想法!谢谢!!

PrivateRoute

interface PrivateRouteProps {
  isLogin: boolean;
  privateRoutes: RouteItem[];
}

const PrivateRoute: React.FunctionComponent<PrivateRouteProps> = (
  props: PrivateRouteProps
) => {
  return (
    <>
      {props.isLogin ? (
        props.privateRoutes.map(item => {
          return <Route key={item.path} {...item} />;
        })
      ) : (
        <Redirect to={PUBLIC.path} />
      )}
    </>
  );
};

PublicRoute

interface PublicProps {
  publicRoutes: RouteItem[];
}

const PublicRoute: React.FC<PublicProps> = (props: PublicProps) => {
  return (
    <>
      {props.publicRoutes.map(route => (
        <Route key={route.path} {...route} />
      ))}
    </>
  );
};

Route

<BrowserRouter>
      <Switch>
        <PublicRoute publicRoutes={publicRoutes} />
        <PrivateRoute privateRoutes={privateRoutes} isLogin={login} />
      </Switch>
    </BrowserRouter>

更新 正如公认的答案所提到的,这完全是关于 &lt;Switch/&gt; 与片段一起使用,所以我修改了我的路线如下,它就像一个魅力。 只需更新它,因为有人可能有类似的问题。

<BrowserRouter>

            <Switch>
                {publicRoutes.map(item => {
                    return <Route key={item.path} {...item}/>
                })}
                {privateRoutes.map(item => {
                    return <PrivateRoute key={item.path}
                                         exact={item.exact}
                                         component={item.component}
                                         path={item.path}
                                         redirectPath={SIGN_IN.path}
                    />

      })}
            </Switch>
        </BrowserRouter>

【问题讨论】:

  • 你能告诉我们你的公共路由组件和你的私有路由道具吗?
  • 嗨@iwaduarte,感谢您的回复!公共和私人路线道具只是&lt;Route /&gt; 需要的道具。我认为他们可能与这个问题无关,所以我没有发布:)
  • 您需要 return 映射数组,但可能不是您的问题的原因,codeandbox 将有助于回答。
  • 嗨@Anuja,感谢您的回复。代码sn-p在这里codesandbox.io/embed/serverless-sunset-8inck
  • @iwaduarte 你好,我将代码更新到代码框,也许你现在可以看看:) 谢谢

标签: reactjs typescript react-router-v4


【解决方案1】:

我浏览了您的代码并归结为一件事。组件&lt;Switch&gt; 与片段&lt;&gt;&lt;/&gt; 一起使用的方式。它只查找第一个 React Fragment,因为它们不想横切一棵树:

https://github.com/ReactTraining/react-router/issues/5785

要解决这个问题,您需要删除组件中的 React.Fragment。 所以您的应用程序将如下所示:

<Switch> 
    <Route ...>
    <Route ...>
    <Route ...>
</Switch>

不是顺便说一句,现在就是这样

      <Switch> 
    //it will only sees the first one //if you switch orders - Private with Public
    // Private will work but not Public anymore :(
        <React.Fragment>
            <Route ...>
            <Route ...>
        </React.Fragment>
        <React.Fragment>
            <Route ...>
        </React.Fragment>
     </Switch>

另一个解决方案(这就是我所做的,因为我对 TypeScript 的了解不足以更改类型和返回)是在你的 switch 应用程序中添加一个 wrapper 并处理私有的返回在&lt;Route&gt;中使用render方法的路由如下所示:

  //index.tsx
        <Switch>
            <>
            <PublicRoute publicRoutes={publicRoutes}/>
            <PrivateRoute privateRoutes={privateRoutes} isLogin={login}/>
            </>
        </Switch>

这会导致无限循环重新渲染的另一个错误(同样,react-router 可能对嵌套路由有不好的时间)并解决您将对 PrivateRoutes 执行以下操作的问题组件:

  //PrivateRoute.tsx
return (
    <>
        {props.privateRoutes.map(item =>
            <Route key={item.path} exact path={item.path} render={() => (
                !props.isLogin
                    ? (
                    <Redirect to={PUBLIC.path}/>
                ):
                    //HOC transforming function Component into Component
                    // @ts-ignore (you can deal here better than me hehehe)
                    ((PrivateComponent)=><PrivateComponent/>)(item.component)
            )}/>)}
    </>
);

TL,DR:您通过在结构中添加&lt;&gt;&lt;/&gt;(翻译为React.Fragment)来增加嵌套复杂性。如果你删除它们或按照上面的代码,你应该没问题

希望我对你有所帮助。祝你好运! :)

【讨论】:

  • 您好!非常感谢!在你回答之后,我真的意识到这只是一个简单的问题 :( 它真的很有帮助。你是对的,太多的 &lt;&gt;&lt;/&gt; 搞砸了路线。我实际上只是将这两个 Routes 映射放在 &lt;Switch&gt; 下,而不是创建两个组件。一切都解决了。再次感谢!
猜你喜欢
  • 2017-07-30
  • 1970-01-01
  • 2017-08-10
  • 1970-01-01
  • 2018-12-14
  • 2023-02-23
  • 2015-09-14
  • 2016-10-13
  • 1970-01-01
相关资源
最近更新 更多