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

React Native中不同屏幕间传递数据的正确方式是什么?

问题描述

我目前通过React Navigation的参数在两个屏幕间传递对象,代码能正常运行:

第一个屏幕代码

export const FirstScreen = ({ navigation }) => {
  const object = {
    name: "John",
    surname: "Smith"
  };

  return (
    <View>
      <Button
        onPress={() =>
          navigation.navigate("MainStack", {
            screen: "SecondScreen",
            params: { object: object },
          })
        }
      />
    </View>
  );
};

第二个屏幕代码

export const SecondScreen = ({ route }) => {
  const [object, setObject] = useState({});

  useEffect(() => {
    if (route.params?.object) setObject(route.params?.object);
  }, []);

  return (
    <View>
      <Text> {object.name} </Text>
      <Text> {object.surname} </Text>
    </View>
  );
};

不过根据React Navigation文档的说法,这种做法属于反模式,核心原因是没必要重复传递完整数据:

要明确参数里应该放什么数据。参数就像屏幕的配置选项,只应该包含用来配置屏幕显示的信息。别直接传屏幕要展示的完整数据(比如传用户ID而非用户对象)。另外,多个屏幕都会用到的数据也不该放在参数里,这类数据应该存到全局状态中。

我知道应该改用全局状态+导航参数定位数据的模式,Redux感觉大材小用,React Context看起来更适配,但有没有更优的、被业界认可的最佳实践方案?


最佳实践方案

针对这类场景,除了React Context,还有几种更贴合React生态的常用方案,都是行业内公认的最佳实践:

1. React Query/SWR(推荐用于后端数据场景)

如果你的数据是从后端获取的,用React Query或SWR这类数据请求库是最优解。它们自带缓存、数据同步能力,本质上是把数据存在全局缓存中:

  • 导航时只传数据的唯一标识(比如用户ID)
  • 目标屏幕通过这个标识从缓存/后端拉取完整数据
  • 优势:自动处理缓存过期、后台同步,不用手动维护全局状态,代码更简洁

示例代码:

// 第一个屏幕
export const FirstScreen = ({ navigation }) => {
  const userId = "123"; // 数据的唯一标识
  return (
    <View>
      <Button
        onPress={() =>
          navigation.navigate("MainStack", {
            screen: "SecondScreen",
            params: { userId },
          })
        }
      />
    </View>
  );
};

// 第二个屏幕
export const SecondScreen = ({ route }) => {
  const { userId } = route.params;
  // 用useQuery从缓存/后端获取数据
  const { data: user } = useQuery(["user", userId], () => fetchUserById(userId));

  if (!user) return <Text>加载中...</Text>;

  return (
    <View>
      <Text>{user.name}</Text>
      <Text>{user.surname}</Text>
    </View>
  );
};

2. Zustand/Jotai(推荐用于前端本地数据场景)

如果数据是前端生成、不需要和后端同步的,Zustand或Jotai这类轻量状态库比Redux轻便太多,也比Context更易用:

  • 定义一个全局状态存储所有数据
  • 导航时传唯一标识,目标屏幕从状态中根据标识提取对应数据
  • 优势:API极简,不需要像Context那样套多层Provider,性能表现也更好

示例(Zustand):

// store.js
import { create } from 'zustand';

export const useUserStore = create((set) => ({
  users: {
    "123": { name: "John", surname: "Smith" }
  },
  addUser: (user) => set((state) => ({ users: {...state.users, [user.id]: user } }))
}));

// 第一个屏幕
export const FirstScreen = ({ navigation }) => {
  const userId = "123";
  return (
    <View>
      <Button
        onPress={() =>
          navigation.navigate("MainStack", {
            screen: "SecondScreen",
            params: { userId },
          })
        }
      />
    </View>
  );
};

// 第二个屏幕
export const SecondScreen = ({ route }) => {
  const { userId } = route.params;
  const user = useUserStore(state => state.users[userId]);

  return (
    <View>
      <Text>{user.name}</Text>
      <Text>{user.surname}</Text>
    </View>
  );
};

3. 继续使用React Context(适合简单场景)

如果你的项目已经在使用Context,或者业务场景非常简单,继续用Context完全没问题,只需注意不要把Context拆得太细导致多层嵌套即可。

总结

  • 数据来自后端:优先选React Query/SWR,自带缓存和同步,减少状态维护成本
  • 前端本地数据:选Zustand/Jotai,比Context更轻便
  • 极小项目/已有Context依赖:继续用Context也完全可行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 06:36:17