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

如何使用Expo Router在页面间传递对象(无需URL参数)

Expo Router 无需URL参数传递对象的实现方法

问题核心

你当前通过router.push的params传对象的方式,会把对象序列化为URL参数,导致URL臃肿、特殊字符转义等问题,完全没必要。下面给你两种实用的解决方案:


方法一:利用router的state传递内存态对象

这是最简单的方案,对象仅存在内存中,不会暴露在URL里,适合纯移动端场景(移动端不会主动刷新页面)。

1. 修改列表页的跳转函数

把对象放在router.push的第二个参数(state)中:

import { useRouter } from 'expo-router';

const getDetails = (item) => {
  const router = useRouter();
  router.push(
    { pathname: `/details/${item.id}` }, // 仅保留必要的ID在URL(也可以直接写'/details')
    { state: { item } } // 完整对象存在内存态,不会出现在URL中
  );
};

2. 详情页获取对象

通过router.state直接取出传递的对象:

import { useRouter } from 'expo-router';
import { Text, Image } from 'react-native';

export default function DetailsPage() {
  const router = useRouter();
  const item = router.state?.item;

  // 处理用户直接访问详情页的情况
  if (!item) {
    return <Text>暂无数据</Text>;
  }

  return (
    <>
      <Image source={{ uri: item.imageURL }} style={{ width: 200, height: 200 }} />
      <Text>{item.title}</Text>
      {/* 渲染其他字段 */}
    </>
  );
}

方法二:全局状态管理(适合跨页面共享/持久化场景)

如果需要在多个页面共享数据,或者担心web端刷新页面丢失数据,可以用React Context或轻量状态库(比如Zustand、Jotai)。这里以React Context为例:

1. 创建全局Context

// context/SelectedItemContext.js
import { createContext, useContext, useState } from 'react';

const SelectedItemContext = createContext();

export const SelectedItemProvider = ({ children }) => {
  const [selectedItem, setSelectedItem] = useState(null);
  return (
    <SelectedItemContext.Provider value={{ selectedItem, setSelectedItem }}>
      {children}
    </SelectedItemContext.Provider>
  );
};

export const useSelectedItem = () => useContext(SelectedItemContext);

2. 在根布局中注入Provider

// app/_layout.jsx
import { SelectedItemProvider } from '../context/SelectedItemContext';
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <SelectedItemProvider>
      <Stack />
    </SelectedItemProvider>
  );
}

3. 列表页设置选中对象

import { useRouter } from 'expo-router';
import { useSelectedItem } from '../context/SelectedItemContext';

const getDetails = (item) => {
  const router = useRouter();
  const { setSelectedItem } = useSelectedItem();
  
  setSelectedItem(item);
  router.push(`/details/${item.id}`);
};

4. 详情页获取对象

import { useSelectedItem } from '../context/SelectedItemContext';
import { Text, Image } from 'react-native';

export default function DetailsPage() {
  const { selectedItem } = useSelectedItem();

  if (!selectedItem) {
    return <Text>暂无数据</Text>;
  }

  return (
    <>
      <Image source={{ uri: selectedItem.imageURL }} style={{ width: 200, height: 200 }} />
      <Text>{selectedItem.title}</Text>
      {/* 渲染其他字段 */}
    </>
  );
}

注意事项

  • 方法一的state在web端刷新页面后会丢失,移动端无此问题;
  • 如果需要持久化数据,可以在全局状态中配合AsyncStorage存储对象;
  • 尽量避免在URL参数中传递复杂对象,不仅影响URL美观,还可能出现编码解码问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:17:35