You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo Router中使用router.push()传递参数失败求助

Expo Router中router.push()传递参数失败,query/params为undefined

问题详情

我是React Native入门开发者,学习使用Expo Router的router.push()在页面间传递参数时遇到问题:调用router.push()传入query参数后,目标页面通过useRouter()获取的query为undefined,报错“Cannot read property 'name' of undefined”,改用params结果一样。试了官方文档、网络搜索和AI工具的方法都没解决。

项目结构

-app
  -_layout.jsx
  -index.jsx
  -user.jsx
-components
  -CustomButton.jsx

现有代码

_layout.jsx

import '../global.css' // Inserts the global css file for tailwind
import { Stack } from 'expo-router'

const App = () => {
  return (
    <Stack>
      <Stack.Screen name='index' />
      <Stack.Screen name='user' />
    </Stack>
  )
}

export default App

CustomButton.jsx

import { View, Text, TouchableOpacity } from 'react-native'
import React from 'react'

const CustomButton = ({ title, styles, onPress }) => {
    return (
        <TouchableOpacity
            className={`border p-2 mt-1 ${styles}`}
            onPress={onPress}
        >
            <View>
                <Text className='text-[20px] text-center'>{title}</Text>
            </View>
        </TouchableOpacity>
    )
}

export default CustomButton

index.jsx

import { SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context'
import { StatusBar } from 'expo-status-bar'
import { View, Text } from 'react-native'
import React from 'react'
import { useRouter } from 'expo-router'

import CustomButton from '../components/CustomButton'

const Home = () => {
    const router = useRouter()

    return (
        <SafeAreaProvider>
            <SafeAreaView className='flex-1 items-center justify-center p-4'>
                <Text className='text-5xl font-bold'>Home Page</Text>
                <CustomButton
                    title={'User'}
                    styles={'w-full bg-blue-300 rounded-[2vw]'}
                    onPress={() =>
                        router.push({
                            pathname: '/user',
                            query: {
                                name: 'Vincent',
                            },
                        })
                    }
                />
                <StatusBar style='dark' />
            </SafeAreaView>
        </SafeAreaProvider>
    )
}

export default Home

user.jsx

import { SafeAreaView, SafeAreaProvider } from 'react-native-safe-area-context'
import { StatusBar } from 'expo-status-bar'
import { View, Text } from 'react-native'
import React from 'react'
import { useRouter } from 'expo-router'

import CustomButton from '../components/CustomButton'

const User = () => {
    const { query } = useRouter()
    console.log(query)

    return (
        <SafeAreaProvider>
            <SafeAreaView className='flex-1 items-center justify-center'>
                <Text className='text-5xl font-bold'>User Page</Text>
                <Text className='text-3xl font-bold'>
                    Welcome, {query.name}
                </Text>
                <StatusBar style='dark' />
            </SafeAreaView>
        </SafeAreaProvider>
    )
}

export default User

依赖版本

{
  "name": "react-native-tutorial",
  "version": "1.0.0",
  "main": "expo-router/entry",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "expo": "~52.0.28",
    "expo-constants": "~17.0.5",
    "expo-linking": "~7.0.5",
    "expo-router": "~4.0.17",
    "expo-status-bar": "~2.0.1",
    "nativewind": "^4.1.23",
    "react": "18.3.1",
    "react-native": "0.76.6",
    "react-native-reanimated": "^3.16.7",
    "react-native-safe-area-context": "^4.12.0",
    "react-native-screens": "~4.4.0",
    "tailwindcss": "^3.4.17"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

解决方法

核心问题:参数获取方式错误

Expo Router v4版本中,useRouter()不再直接暴露query或params对象,需要使用专门的useLocalSearchParams()钩子来获取路由传递的query参数。

修改user.jsx代码

将原来的参数获取逻辑替换为useLocalSearchParams():

import { SafeAreaView } from 'react-native-safe-area-context'
import { StatusBar } from 'expo-status-bar'
import { View, Text } from 'react-native'
import React from 'react'
import { useLocalSearchParams } from 'expo-router'

const User = () => {
    const query = useLocalSearchParams()
    console.log(query)

    return (
        <SafeAreaView className='flex-1 items-center justify-center'>
            <Text className='text-5xl font-bold'>User Page</Text>
            {/* 增加默认值避免参数不存在时报错 */}
            <Text className='text-3xl font-bold'>
                Welcome, {query.name || 'Guest'}
            </Text>
            <StatusBar style='dark' />
        </SafeAreaView>
    )
}

export default User

额外优化:避免重复渲染SafeAreaProvider

不要在每个页面都包裹SafeAreaProvider,将其移到根布局_layout.jsx中,减少嵌套和不必要的组件渲染:

优化后的_layout.jsx

import '../global.css'
import { Stack } from 'expo-router'
import { SafeAreaProvider } from 'react-native-safe-area-context'

const App = () => {
  return (
    <SafeAreaProvider>
      <Stack>
        <Stack.Screen name='index' />
        <Stack.Screen name='user' />
      </Stack>
    </SafeAreaProvider>
  )
}

export default App

优化后的index.jsx(移除内部的SafeAreaProvider)

import { SafeAreaView } from 'react-native-safe-area-context'
import { StatusBar } from 'expo-status-bar'
import { View, Text } from 'react-native'
import React from 'react'
import { useRouter } from 'expo-router'

import CustomButton from '../components/CustomButton'

const Home = () => {
    const router = useRouter()

    return (
        <SafeAreaView className='flex-1 items-center justify-center p-4'>
            <Text className='text-5xl font-bold'>Home Page</Text>
            <CustomButton
                title={'User'}
                styles={'w-full bg-blue-300 rounded-[2vw]'}
                onPress={() =>
                    router.push({
                        pathname: '/user',
                        query: {
                            name: 'Vincent',
                        },
                    })
                }
            />
            <StatusBar style='dark' />
        </SafeAreaView>
    )
}

export default Home

内容的提问来源于stack exchange,提问作者Vince

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:21:01