React Navigation--Stack Navigator 详细的例子

本文将通过一个详细的实例,全面解析React Navigation中的Stack Navigator组件的使用方法,包括导航配置、页面间跳转以及自定义导航栏等核心概念。
/**
 * Created by YiBing on 2017/5/5.
 *
 * 一个StackNavigator详细的例子,效果:1个主页面,2个子页面,每个页面有三个按钮,可以跳转到相应的页面。
 *
 * React Navigation -- StackNavigator:
 API Definition--StackNavigator(RouteConfigs, StackNavigatorConfig);
 RouteConfigs--StackNavigator({

  // For each screen that you can navigate to, create a new entry like this:
  Profile: {

    // `ProfileScreen` is a React component that will be the main content of the
screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a
`navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is
used:
    path: 'people/:username',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({navigation}) => ({
      title: `${navigation.state.params.username}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});

 StackNavigatorConfig--
 initialRouteName:默认路由,就是第一个要显示的页面。
 initialRouteParams;
 navigationOptions:对所有的screen的默认配置。
 paths:对所有路由的path属性的默认配置。
 mode:定义渲染风格,enum(card(IOS、Android都可以)、modal(仅IOS))。
 headerMode:enum(float、screen、none)。
 cardStyle:Use this prop to override or extend the default style for an individual
 card in stack.
 transitionConfig:Function to return an object that overrides default screen
 transitions.
 onTransitionStart:Function to be invoked when the card transition animation is about
 to start.
 onTransitionEnd:Function to be invoked once the card transition animation completes.


 Screen Navigation Options:
 title: Generic title that can be used as a fallback for headerTitle and tabBarLabel。
 headerRight:React Element to display on the right side of the header。
 header
 headerTitle
 headerBackTitle:Title string used by the back button on iOS or null to disable
 label. Defaults to scene title。
 headerTruncatedBackTitle
 headerLeft
 headerStyle
 headerTitleStyle
 headerBackTitleStyle
 headerTintColor
 headerPressColorAndroid:Color for material ripple (Android >= 5.0 only)
 gesturesEnabled


 Navigator Props:
 const SomeStack = StackNavigator({
    // config
  });
 <SomeStack
 screenProps={
     // this prop will get passed to the screen components asthis.props.screenProps
   } />
*/

import React from 'react';
import {
    Button,
    ScrollView,
    Text,
} from 'react-native';
import {
    StackNavigator,
} from 'react-navigation';

const MyNavScreen = ({navigation, banner}) => (
    <ScrollView>
        <Text>{banner}</Text>
        <Button
            onPress={() => navigation.navigate('Profile', { name: 'Jane' })}
            title="Go to a profile screen"
        />
        <Button
            onPress={() => navigation.navigate('Photos', { name: 'Jane' })}
            title="Go to a photos screen"
        />
        <Button
            onPress={() => navigation.goBack(null)}
            title="Go back"
        />
    </ScrollView>
);

const MyHomeScreen = ({navigation}) => (
    <MyNavScreen
        banner="Home Screen"
        navigation={navigation}
    />
);
MyHomeScreen.navigationOptions = {
    title: 'Welcome',
};

const MyPhotosScreen = ({navigation}) => (
    <MyNavScreen
        banner={`${navigation.state.params.name}'s Photos`}
        navigation={navigation}
    />
);
MyPhotosScreen.navigationOptions = {
    title: 'Photos',
};

const MyProfileScreen = ({navigation}) => (
    <MyNavScreen
        banner={
            `${navigation.state.params.mode === 'edit' ? 'Now Editing ' : ''}${navigation.state.params.name}'s Profile`
        }
        navigation={navigation}
    />
);

MyProfileScreen.navigationOptions = props => {
    const {navigation} = props;
    const {state, setParams} = navigation;
    const {params} = state;
    return {
        headerTitle: `${params.name}'s Profile!`,
        // Render a button on the right side of the header.
        // When pressed switches the screen to edit mode.
        headerRight: (
            <Button
                title={params.mode === 'edit' ? 'Done' : 'Edit'}
                onPress={() => setParams({ mode: params.mode === 'edit' ? '' : 'edit' })}
            />
        ),
    };
};

const SimpleStack = StackNavigator(
    {
        Profile: {
            path: 'people/:name',
            screen: MyProfileScreen,
        },
        Photos: {
            path: 'photos/:name',
            screen: MyPhotosScreen,
        },
        Home: {
            screen: MyHomeScreen,
        },
    },
    {
        initialRouteName: 'Home',
    }
);

export default SimpleStack;









<think> 我们正在处理关于`@react-navigation/native-stack`的查询,用户希望了解其使用方法、安装步骤以及与之前错误(TS2307)的关联解决方案。 根据之前的对话,用户遇到了`react-navigation-stack`模块找不到的类型错误,而我们已经建议迁移到`@react-navigation/native-stack`。现在用户明确要求关于`native-stack`的信息。 ### 解决方案思路: 1. **安装说明**:如何安装`@react-navigation/native-stack`以及其依赖。 2. **基本用法**:如何设置堆栈导航器,包括定义屏幕和导航器。 3. **类型安全配置**:如何配置TypeScript以避免之前出现的类型错误。 4. **迁移建议**:从`react-navigation-stack`迁移到`native-stack`的关键步骤。 5. **常见问题**:可能遇到的问题及解决方案。 ### 完整回答: #### 📦 1. 安装 `@react-navigation/native-stack` 首先,确保已经安装了React Navigation的核心库和原生依赖: ```bash # 安装核心包 npm install @react-navigation/native # 安装原生依赖(Expo项目) npx expo install react-native-screens react-native-safe-area-context # 安装native-stack npm install @react-navigation/native-stack ``` #### 2. 基本使用方法 在应用中设置堆栈导航器: ```typescript // App.tsx import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; // 创建堆栈导航器 const Stack = createNativeStackNavigator(); function HomeScreen() { return <View><Text>Home</Text></View>; } function DetailsScreen() { return <View><Text>Details</Text></View>; } export default function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Details" component={DetailsScreen} /> </Stack.Navigator> </NavigationContainer> ); } ``` #### 🔐 3. TypeScript 类型安全配置 为了避免之前的类型错误(TS2307),需要确保: 1. 安装正确的类型声明包(`@types/react-navigation`已不再需要,因为`@react-navigation/native-stack`自带类型) 2. 在`tsconfig.json`中添加路径映射(可选,通常不需要): ```json { "compilerOptions": { "paths": { "@react-navigation/*": ["node_modules/@react-navigation/*"] } } } ``` #### 🔄 4. 从 `react-navigation-stack` 迁移到 `native-stack` 关键变更点: - 导入方式:`createStackNavigator` 改为 `createNativeStackNavigator` - 配置选项:`native-stack`使用原生导航组件,配置选项略有不同(例如:`headerMode`不再存在,改为在屏幕选项中设置) ```diff - import { createStackNavigator } from 'react-navigation-stack'; + import { createNativeStackNavigator } from '@react-navigation/native-stack'; ``` #### 5. 常见问题解决 - **类型错误 TS2307**:如果遇到`@react-navigation/native-stack`找不到,尝试: ```bash npm install @types/react-navigation__native-stack --save-dev ``` 但通常不需要,因为该包已包含类型定义。 - **Expo兼容性**:确保使用兼容的Expo SDK版本(>= 43,推荐>= 46)[^1]。 #### 🌟 最佳实践 - 使用`native-stack`以获得更好的性能和原生体验。 - 通过`screenOptions`统一配置所有屏幕的导航栏样式: ```typescript <Stack.Navigator screenOptions={{ headerShown: false, // 隐藏所有标题栏 }} > ``` §§ 生成的相关问题 §§ 1. 如何在React Navigation中实现底部选项卡导航? 2. `@react-navigation/native-stack`与`@react-navigation/stack`有何区别? 3. 如何自定义导航栏标题和样式? 4. 在React Navigation中如何进行路由传参? </think> ### 🚀 React Navigation Native Stack 使用指南 #### 📦 安装步骤 ```bash # 安装核心包 npm install @react-navigation/native # 安装原生依赖(Expo项目) npx expo install react-native-screens react-native-safe-area-context # 安装 Native Stack 导航器 npm install @react-navigation/native-stack ``` #### ️ 基本使用方法 ```typescript import * as React from 'react'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; const Stack = createNativeStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home" screenOptions={{ headerShown: false }} > <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Details" component={DetailsScreen} options={{ title: '详情页' }} /> </Stack.Navigator> </NavigationContainer> ); } ``` #### 🔒 解决之前提到的 TS2307 错误 迁移到 Native Stack 可彻底修复 `react-navigation-stack` 的类型错误: 1. **替换导入语句**: ```diff - import { createStackNavigator } from 'react-navigation-stack'; + import { createNativeStackNavigator } from '@react-navigation/native-stack'; ``` 2. **类型兼容性**: ```typescript // tsconfig.json 确保包含 { "compilerOptions": { "types": ["react-native", "@react-navigation/native"] } } ``` #### 🌟 核心功能详解 1. **导航参数传递**: ```typescript // 发送参数 navigation.navigate('Profile', { userId: '123' }); // 接收参数(函数组件) function ProfileScreen({ route }) { return <Text>用户ID: {route.params.userId}</Text>; } ``` 2. **自定义导航栏**: ```typescript <Stack.Screen name="Settings" component={SettingsScreen} options={{ title: '我的设置', headerStyle: { backgroundColor: '#4CAF50' }, headerTintColor: '#fff', headerRight: () => <Button title="保存" /> }} /> ``` 3. **嵌套导航结构**: ```typescript function TabsNavigator() { return ( <Tab.Navigator> <Tab.Screen name="Feed" component={FeedScreen} /> <Tab.Screen name="Messages" component={MessagesScreen} /> </Tab.Navigator> ); } // 在主堆栈中嵌套 <Stack.Screen name="MainTabs" component={TabsNavigator} /> ``` #### ⚠️ 常见问题解决 1. **类型声明缺失**: ```bash npm install @types/react-navigation__native-stack --save-dev ``` 2. **Expo 兼容性问题**: ```bash npx expo install @react-navigation/native-stack ``` 3. **调试工具集成**: 安装 [React Native Debugger](https://github.com/jhen0409/react-native-debugger) 可视化导航状态[^3] #### 💡 性能优化建议 1. 使用 `React.memo()` 包装屏幕组件减少重渲染 2. 懒加载不常用屏幕: ```typescript const DetailsScreen = React.lazy(() => import('./DetailsScreen')); ``` 3. 关闭非活跃屏幕的渲染: ```javascript <Stack.Navigator detachInactiveScreens={true}> ``` > Native Stack 使用原生导航组件(UINavigationController 等),相比 JS 实现的 Stack 导航器有更好的性能和原生体验[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值