4

我对 React 和 Ionic 还很陌生。我试图完成的是创建一个“受保护的路线”。我创建了一个简单的上下文,称为AuthContext

import { createContext, Dispatch } from 'react';

/**
 * Context interface for AuthAuthentication/Authorization
 *
 * @property isAuthenticated
 * @property dispatch
 *
 * @interface
 */
interface AuthDefaultContext {
    isAuthenticated: boolean;
    dispatch: Dispatch<any>
}

/**
 * Authentication/Authorization context for managing
 * authenticating/ed and authorizing/ed users
 */
export const AuthContext = createContext<AuthDefaultContext>({
    isAuthenticated: false,
    dispatch: () => {}
});

和 FunctionalComponent 称为ProtectedRoute

interface ProtectedRouteProps {
    ProtectedComponent: FunctionComponent,
    routePath: string
}

export const ProtectedRoute: FunctionComponent<ProtectedRouteProps> = ({ ProtectedComponent, routePath }) => {

    useEffect(() => {
        console.log(`loading protected route '${routePath}' with component ${ProtectedComponent.name}`)
    }, [ProtectedComponent, routePath] );

    return (
        <AuthContext.Consumer>
            {
                ({ isAuthenticated }) => (
                    <Route path={ routePath } render={ () => isAuthenticated ? <ProtectedComponent/> : <Redirect to="/login" /> }/>
                )
            }
        </AuthContext.Consumer>
    );
}

在我的主要应用程序组件中,我将IonReactRouter内部包装AuthContext.Provider如下:

        <IonApp>
            <AuthContext.Provider value={{ isAuthenticated: authenticated, dispatch: dispatch }}>
                <IonReactRouter>
                    <IonRouterOutlet>
                        <Route path="/login" component={ Login } exact={ true } />
                        <ProtectedRoute routePath="/welcome" ProtectedComponent={ Welcome }/>
                        <ProtectedRoute routePath="/search" ProtectedComponent={ Dummy }/>
                    </IonRouterOutlet>
                </IonReactRouter>
            </AuthContext.Provider>
        </IonApp>

我遇到的问题是,上述方法适用于常规路线和第一个 ProtectedRoute,但/search/不起作用。浏览器 url 中的 uri 路径更改为,/search但虚拟组件未呈现。

我注意到如果你交换<IonReactRouter>&<IonRouterOutlet>像这样:

            <IonRouterOutlet>
                <IonReactRouter>
                    .....
                </IonReactRouter>
            </IonRouterOutlet>

所有路线都有效,但您失去了IonRouterOutlet. Ionics 网站上的导航文档有IonReactRouter包装IonRouterOutlet,所以我假设这是正确的实现。

如果我将ProtectedRoute's 更改为仅标准反应,则Route所有路线都可以正常使用动画。所以问题必须与我的ProtectedRoute组件实现有关,我只是想不通。非常感激任何的帮助。谢谢!

更新:

我仍然没有找到解决这个问题的方法,所以我删除了 IonRouterOutlet 这似乎是根本原因。这样做时,一切都按预期工作。我在 Ionic 论坛上发布了这个问题,所以当/如果我得到答案时,我会在这里发布。

谢谢,

4

3 回答 3

5

IonRouterOutlet 期望它的子节点要么是 Routes 要么是“Route like”,这意味着子节点需要拥有与 Route 相同的基本属性。

因此,对于您的 ProtectedRoute,如果您将传入的道具重命名routePathpathProtectedComponent,它应该可以工作component

我在这里整理了一个工作示例 repo,从您的代码开始:https ://github.com/elylucas/ionic-react-protected-route

让我知道这是否有帮助。

谢谢

于 2020-03-03T18:31:17.610 回答
3

我发现在 a 上使用道具render会破坏它。RouteIonRouterOutlet

在您的情况下,您必须替换以下内容:

<Route
  path={routePath}
  render={() => isAuthenticated ? <ProtectedComponent/> : <Redirect to="/login" />}
/>

像这样:

{
  isAuthenticated ?
    <Route path={routePath} component={ProtectedComponent} /> :
    <Redirect to="/login" />
}
于 2020-08-14T16:34:55.860 回答
1

我的问题是我有一些页面嵌套在可重用组件“BasicPage”中,这导致了问题:

interface BasicPage extends RouteComponentProps {
  title: string;
  renderContent: any;
  history: any;
  hasMenu: boolean;
  backAction?: any;
}
/**
 * helper Ionic Page which laysout the framework of the page so
 * we dont need to repeat the boilerplate code. We also include
 * the router by default to help with page navigation
 */
const BasicPage: React.FC<BasicPage> = ({
  title,
  renderContent,
  history,
  hasMenu,
  backAction,
}) => {
  return (
    <>
      <IonHeader>
        <IonToolbar color="primary">
          <IonButtons slot="start">
            {hasMenu ? <IonMenuButton /> : null}
            {backAction ? <IonBackButton defaultHref="/" text="" /> : null}
          </IonButtons>
          <IonTitle>{title}</IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>{renderContent(history)}</IonContent>
    </>
  );
};

export default withRouter(BasicPage);

renderContent没有呈现我的页面。我还没有弄清楚这是什么原因,但我现在正试图解决这个问题。

于 2020-03-02T08:23:26.253 回答