React Native中TouchableOpacity页面跳转及导航配置问题求助
我有index.js和HomeScreen.js两个页面,已创建TouchableOpacity按钮,希望点击按钮从index.js跳转到HomeScreen.js。查阅React Navigation相关教程后仍未成功,不确定是代码、操作方式、依赖安装的问题,也怀疑是否因自定义字体加载导致跳转失败。
index.js 代码
import React from 'react' import { View, Text, StyleSheet, TouchableOpacity, Image, ActivityIndicator } from 'react-native'; import * as Font from 'expo-font'; let customFonts = { 'Monospace': require('./assets/fonts/Monospace.ttf'), }; export default class App extends React.Component { state = { fontsLoaded: false, }; async _loadFontsAsync() { await Font.loadAsync(customFonts); this.setState({ fontsLoaded: true }); } componentDidMount() { this._loadFontsAsync(); } render() { if (!this.state.fontsLoaded) { return null; } return( <View style={styles.container}> <Text style={styles.titleText}>Cheqz</Text> <Text style={styles.welcomeText}>Welcome!</Text> <Text style={styles.questionText}>Ready to be productive?</Text> <TouchableOpacity onPress={() => {console.log('Enter button was presssed')}}> <View style={styles.buttonContainer} > <Text style={styles.buttonText}>Enter</Text> </View> </TouchableOpacity> </View> )}; } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#dddddd", alignItems: 'center', justifyContent: 'center', fontSize: 30, }, titleText: { position: 'relative', bottom: 190, fontSize: 55, fontFamily: 'Monospace', backgroundColor: '#cccccc', padding: 50, borderRadius: 200, }, welcomeText: { fontSize: 25, position: 'relative', bottom: 130, fontFamily: 'Monospace', }, questionText: { fontSize: 25, position: 'relative', bottom: 120, fontFamily: 'Monospace', }, buttonContainer: { height: 40, marginHorizontal: 10, backgroundColor: '#cccccc', justifyContent: 'center', alignItems: 'center', padding: -3, paddingRight: 20, paddingLeft: 20, borderRadius: 20, textAlign: 'center', }, buttonText: { textTransform: 'uppercase', color: 'black', fontSize: 25, textAlign: 'center', fontFamily: 'Monospace' }, });
HomeScreen.js 代码
import React from 'react'; import {Text, View} from 'react-native'; const HomeScreen = () => { return( <View style={{flex : 1,justifyContent : 'center',alignContent: 'center'}}> <Text>Home View</Text> </View> ) } export default HomeScreen;
_Layout.js 代码
import { Stack } from 'expo-router'; export default function HomeLayout() { return ( <Stack screenOptions={{ headerStyle: { backgroundColor: '#dddddd' }, title: '', headerTintColor: '#dddddd', headerShadowVisible: false, // applied here headerBackTitleVisible: false, }} /> ) }
参考的React Navigation官网示例
import * as React from 'react'; import { Button, View, Text } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; function HomeScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> </View> ); }
问题分析与解决步骤
1. 核心问题:导航框架不匹配
你使用了expo-router的Stack组件,但参考的是原生React Navigation的示例,两者导航逻辑完全不同。同时你的index.js未接入导航系统,无法获取导航对象完成跳转。
2. 字体加载不影响跳转
Font.loadAsync仅负责加载自定义字体,与导航跳转逻辑完全独立,可排除该因素。
3. 具体修复方案
步骤1:确认expo-router依赖安装
若未安装,执行以下命令:
npx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
步骤2:适配expo-router文件路由规则
expo-router采用文件系统路由,app/目录下的文件对应路由:
app/index.js对应根路由/app/HomeScreen.js对应/HomeScreen路由
步骤3:修改index.js实现跳转
将类组件转为函数组件,使用expo-router的useRouter钩子实现跳转:
import React, { useState, useEffect } from 'react' import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; import * as Font from 'expo-font'; import { useRouter } from 'expo-router'; let customFonts = { 'Monospace': require('./assets/fonts/Monospace.ttf'), }; export default function App() { const [fontsLoaded, setFontsLoaded] = useState(false); const router = useRouter(); async function loadFontsAsync() { await Font.loadAsync(customFonts); setFontsLoaded(true); } useEffect(() => { loadFontsAsync(); }, []); if (!fontsLoaded) { return null; } return( <View style={styles.container}> <Text style={styles.titleText}>Cheqz</Text> <Text style={styles.welcomeText}>Welcome!</Text> <Text style={styles.questionText}>Ready to be productive?</Text> <TouchableOpacity onPress={() => router.push('/HomeScreen')}> <View style={styles.buttonContainer} > <Text style={styles.buttonText}>Enter</Text> </View> </TouchableOpacity> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#dddddd", alignItems: 'center', justifyContent: 'center', fontSize: 30, }, titleText: { position: 'relative', bottom: 190, fontSize: 55, fontFamily: 'Monospace', backgroundColor: '#cccccc', padding: 50, borderRadius: 200, }, welcomeText: { fontSize: 25, position: 'relative', bottom: 130, fontFamily: 'Monospace', }, questionText: { fontSize: 25, position: 'relative', bottom: 120, fontFamily: 'Monospace', }, buttonContainer: { height: 40, marginHorizontal: 10, backgroundColor: '#cccccc', justifyContent: 'center', alignItems: 'center', paddingRight: 20, paddingLeft: 20, borderRadius: 20, }, buttonText: { textTransform: 'uppercase', color: 'black', fontSize: 25, textAlign: 'center', fontFamily: 'Monospace' }, });
步骤4:验证_Layout.js配置
你的_Layout.js已正确配置Stack导航,无需修改,它会自动管理app/目录下的所有路由页面。
4. 额外注意事项
- 类组件需通过
withRouter高阶组件使用expo-router导航,转换为函数组件更简洁 - 确保项目入口为expo-router,
app/_layout.js配置后expo会自动启用该路由系统 - 若之前安装过原生React Navigation依赖(如
@react-navigation/native),可能与expo-router冲突,建议卸载后重新安装expo-router相关依赖
内容的提问来源于stack exchange,提问作者24ycarasco
相关产品推荐
相关产品推荐

