React 导航
本指南介绍在使用 Ionic 和 React 构建的应用中路由的工作原理。
IonReactRouter 底层使用了流行的 React Router 库。借助 Ionic 和 React Router,您可以创建具有丰富页面过渡效果的多页面应用。
您了解的关于使用 React Router 进行路由的所有知识都可以沿用到 Ionic React 中。让我们看看 Ionic React 应用的基础知识以及路由如何与之配合工作。
Ionic React 中的路由
以下是一个示例 App 组件,它定义了一个指向 "/dashboard" URL 的单一路由。当您访问 "/dashboard" 时,该路由会渲染 DashboardPage 组件。
App.tsx
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/dashboard" component={DashboardPage} />
<Redirect exact from="/" to="/dashboard" />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
在 Route 之后,我们定义了默认的 Redirect,当用户访问应用的根 URL ("/") 时,会将其重定向到 "/dashboard" URL。
重定向还设置了 exact 属性,这意味着 URL 必须精确匹配 from 属性(或者如果在 Route 上使用了 exact,则匹配 path 属性)才能匹配此路由。如果没有这个属性,此重定向会对每个路由都生效,因为每个路由都以 "/" 开头。
您还可以根据条件在 Route 的 render 方法中以编程方式进行重定向,例如检查用户是否已认证:
<Route
exact
path="/dashboard"
render={(props) => {
return isAuthed ? <DashboardPage {...props} /> : <LoginPage />;
}}
/>
IonReactRouter
IonReactRouter 组件包装了 React Router 的传统 BrowserRouter 组件,并为应用设置了路由。因此,请使用 IonReactRouter 代替 BrowserRouter。您可以向 IonReactRouter 传递任何属性,这些属性会被传递给底层的 BrowserRouter。
嵌套路由
在 Dashboard 页面内部,我们定义了更多与应用的这一特定部分相关的路由:
DashboardPage.tsx
const DashboardPage: React.FC = () => {
return (
<IonPage>
<IonRouterOutlet>
<Route exact path="/dashboard" component={UsersListPage} />
<Route path="/dashboard/users/:id" component={UserDetailPage} />
</IonRouterOutlet>
</IonPage>
);
};
这里,又定义了几个从仪表盘部分指向页面的路由。请注意,我们需要在路径中定义完整路由,即使我们是通过该 URL 到达此页面的,也不能省略 "/dashboard"。React Router 需要完整路径,不支持相对路径。
但是,我们可以使用 match 对象的 url 属性来提供用于渲染组件的匹配 URL,这在使用嵌套路由时会很有帮助:
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonPage>
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
</IonRouterOutlet>
</IonPage>
);
};
这里,match.url 包含 "/dashboard" 的值,因为该 URL 用于渲染 DashboardPage。
这些路由被 分组在一个 IonRouterOutlet 中,接下来我们讨论它。
IonRouterOutlet
IonRouterOutlet 组件为渲染 Ionic "页面" 的路由提供了一个容器。当页面在 IonRouterOutlet 中时,容器控制页面之间的过渡动画,以及控制页面何时创建和销毁,这有助于在视图之间来回切换时保持状态。
上面的 DashboardPage 显示了一个用户列表页面和一个详情页面。在两个页面之间导航时,IonRouterOutlet 提供适当的平台页面过渡,并保持前一个页面的状态不变,以便当用户导航回列表页面时,它显示为与离开时相同的状态。
IonRouterOutlet 应该只包含 Route 或 Redirect。任何其他组件应该作为 Route 的结果渲染,或者在 IonRouterOutlet 之外渲染。
回退路由
一个常见的路由使用场景是提供一个"回退"路由,以便在导航到的位置与任何已定义的路由都不匹配时渲染。
我们可以通过将一个不带 path 属性的 Route 组件放在 IonRouterOutlet 中最后定义的路由之后来定义回退路由。
DashboardPage.tsx
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
<Route render={() => <Redirect to={match.url} />} />
</IonRouterOutlet>
);
};
在这里,我们可以看到,如果某个位置与前两个 Route 都不匹配,IonRouterOutlet 会将 Ionic React 应用重定向到 match.url 路径。
您也可以提供一个要渲染的组件来代替重定向。
const DashboardPage: React.FC<RouteComponentProps> = ({ match }) => {
return (
<IonRouterOutlet>
<Route exact path={match.url} component={UsersListPage} />
<Route path={`${match.url}/users/:id`} component={UserDetailPage} />
<Route component={NotFoundPage} />
</IonRouterOutlet>
);
};
IonPage
IonPage 组件包装 Ionic React 应用中的每个视图,并使页面过渡和堆栈导航正常工作。使用路由器导航到的每个视图都必须包含 IonPage 组件。
IonPage 也是正确样式所必需的。它提供了一个 flex 容器,确保页面内容(如 IonContent)大小合适,不会与其他 UI 元素(如 IonTabBar)重叠。
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import React from 'react';
const Home: React.FC = () => {
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonTitle>首页</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent className="ion-padding">Hello World</IonContent>
</IonPage>
);
};
export default Home;