For the complete documentation index, see llms.txt. This page is also available as Markdown.

页面跳转

在 Granite 应用中,可以轻松处理页面切换、历史记录管理、参数传递等路由功能。内部则是 React Navigation基于其运行,因此可以直接用熟悉的 API 来使用。

WebView 路由

在 WebView 环境中,会原封不动地遵循你在项目中配置的 Web 路由器(例如 React Router)规则,无需修改。

路由示例结构

路由示例共由 3 个页面(page-a, page-b, page-c)组成。

root
├─── pages
│    ├─── page-a.tsx
│    ├─── page-b.tsx
│    └─── page-c.tsx
└─── src
     └─── ...
`page-a.tsx` 源代码
// page-a.tsx
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { createRoute, useNavigation } from '@granite-js/react-native';

export const Route = createRoute('/page-a', {
  validateParams: (params) => params,
  component: PageA,
});

function PageA() {
  const navigation = useNavigation();

  const handlePress = () => {
    navigation.navigate('/page-b');
  };

  return (
    <View style={[styles.container, { backgroundColor: '#3182f6' }]}>
      <Text style={styles.text}>Page A</Text>
      <Pressable onPress={handlePress}>
        <Text style={styles.buttonLabel}>跳转到 B 页面</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
`page-b.tsx` 源代码
// page-b.tsx
import { createRoute, useNavigation } from '@granite-js/react-native';
import { StyleSheet, View, Text, Pressable } from 'react-native';

export const Route = createRoute('/page-b', {
  validateParams: (params) => params,
  component: PageB,
});

function PageB() {
  const navigation = useNavigation();

  // 返回上一页的函数。
  const handlePressBackButton = () => {
    if (navigation.canGoBack()) {
      navigation.goBack();
    } else {
      console.warn('无法返回上一页。');
    }
  };

  const handlePressNextButton = () => {
    navigation.navigate('/page-c', {
      message: '你好!',
      date: new Date().getTime(),
    });
  };

  return (
    <View style={[styles.container, { backgroundColor: '#fe9800' }]}>
      <Text style={styles.text}>Page B</Text>
      <Pressable onPress={handlePressBackButton}>
        <Text style={styles.buttonLabel}>返回上一页</Text>
      </Pressable>
      <Pressable onPress={handlePressNextButton}>
        <Text style={styles.buttonLabel}>跳转到 C 页面</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
`page-c.tsx` 源代码

页面 A:页面跳转

useNavigation用于处理页面之间的跳转。 navigate 可通过该方法同时传递要跳转的页面路径和所需数据。

关键点

  • useNavigation 使用 Hook 取得 navigation 对象。

  • navigation.navigate('/page-b')调用后会跳转到 'B' 页面。

页面 B:返回上一页

goBack 方法可以返回上一页。不过,如果没有上一页记录,可能会发生错误,因此, canGoBack要先进行确认。

关键点

  • canGoBack()先用它确认是否有上一页,如果有, goBack()就会被调用。

  • navigate('/page-c', { message: '你好!', date: new Date().getTime() })在传递数据的同时跳转到 'C' 页面。

页面 C:使用传入的数据

Route.useParams Hook 用于获取从其他页面传来的数据。

此时, createRoute.validateParams 如果设置该选项,就可以在进行类型校验(Type-Safe)的同时访问传入的数据。这样可以避免因错误的数据格式导致的错误。

关键点

  • Route.useParams 使用 Hook 可以访问从 URL 传来的数据(参数)。

  • createRoute.validateParams 设置该选项后,可以在进行类型校验(Type-Safe)的同时安全使用数据。

定义页面参数类型

每个页面都定义如下的 Route 组件。其中 validateParams 选项用于定义该页面接收的参数类型。

在上面的代码中, validateParams消息date和 message 这两个字段的参数定义为类型。

通过这样, useNavigateuseParams在使用时,可以通过类型检查清楚地了解所需路径和应传递的数据。这样能提高代码的安全性和可读性。


自动生成类型定义

在开发模式下, pages/ 当目录中添加文件时,会自动生成类型定义,因此无需执行额外命令。

生成的文件示例

自动生成的文件如下。由于是自动生成的文件,无需手动修改。

关键点

  • 为各页面接收的参数类型 createRoute.validateParams 如果通过该选项预先定义, navigateparams 在使用时就能进行类型检查,从而更安全地编写代码。

  • 在开发模式下, pages/ 当目录中添加文件时,类型定义会自动生成,因此无需单独执行命令。

这样使用 React Navigation,就可以轻松处理页面间跳转,并通过传递数据或操作记录等功能实现多样的 UX。此外,配合 TypeScript 使用,还能编写安全而稳健的代码。

重置路由状态

按“页面 A → 页面 B → 页面 C”的顺序跳转后,状态可以如下图所示表示。

页面 A、页面 B、页面 C 按顺序 routes 保留在记录中, index 值指向最后跳转到的页面 C 的位置 2。

reset使用 reset 可以初始化页面跳转记录。例如,如果在跳转到“页面 A → B → C”之后,想返回“页面 A”并删除 B 和 C 的记录, CommonActions.reset

关键点

  • CommonActions.reset就可以只保留特定页面的记录,并删除其余页面的记录。

参考资料

最后更新于

这有帮助吗?