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

React Native跨屏日期显示旧数据错误的解决求助

React Native 页面间日期传递异常问题

我接触React Native开发时间不长,近期遇到一个问题:需要将日历选中的日期数据传递到其他页面。最初尝试页面间直接共享数据但持续报错,于是改用AsyncStorage将日期转为字符串存储的方式实现数据传递,该方法能成功传递数据但存在严重问题:
首次启动应用选择2月1日,跳转页面后日期未显示;返回首页选择2月2日,跳转后页面显示的却是2月1日,即详情页总是显示上一次选中的日期而非当前选中的日期。

代码示例

Home.js

import React from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Calendar } from "react-native-calendars";
import { View, Alert } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

var dateString = "";

const savereturndate = async (value) => {
  try {
    await AsyncStorage.setItem("selectdate", dateString);
  } catch (e) {
    Alert.alert("Error", e, [{ text: "OK", onPress: () => null }]);
  }
};

function HomeScreen({ navigation }) {
  const markedDates = {
    "2023-02-01": { marked: true, dotColor: "red" },
  };
  return (
    <SafeAreaProvider>
      <View>
        <Calendar
          markedDates={markedDates}
          onDayPress={(day) => {
            for (var key in day) {
              //console.log("key:" + key + "/" + day[key])
              dateString = day[key];
            }
            savereturndate();
            navigation.push("Detail");
          }}
        />
      </View>
    </SafeAreaProvider>
  );
}

export default HomeScreen;

Detail.js

import React from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { View, Text, Alert } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

var returndatedetail = "";

const getreturndate = async () => {
  try {
    const hello = await AsyncStorage.getItem("selectdate");
    returndatedetail = hello.toString();
  } catch (e) {
    Alert.alert("Error", e, [{ text: "OK", onPress: () => null }]);
  }
};

function DetailScreen() {
  getreturndate();
  return (
    <SafeAreaProvider>
      <View>
        <Text>{returndatedetail}</Text>
      </View>
    </SafeAreaProvider>
  );
}

export default DetailScreen;

开发环境

  • OS:macOS Monterey(12.6.3)
  • 开发工具:Visual Studio Code (1.71.1)
  • 模拟器:iPhone 14 (iOS 16.2)
  • React Native版本:9.2.0
  • 测试方式:使用Expo Go进行测试

问题原因及修复方案

核心问题

  1. 异步操作未等待:savereturndate是异步函数,调用后立刻跳转页面,此时AsyncStorage可能还未完成存储,导致详情页读取旧数据
  2. 无状态更新触发渲染:直接修改全局变量returndatedetail,组件不会自动重新渲染,新数据无法显示
  3. 日期提取错误:遍历day对象会把最后一个属性(如timestamp)赋值给dateString,而非目标日期字符串

修复步骤

1. 修正Home.js的存储逻辑

  • 直接通过day.dateString获取选中日期,无需遍历
  • 等待存储完成后再跳转页面
  • 移除全局变量,改用局部变量

修改后的Home.js:

import React from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Calendar } from "react-native-calendars";
import { View, Alert } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

const savereturndate = async (date) => {
  try {
    await AsyncStorage.setItem("selectdate", date);
  } catch (e) {
    Alert.alert("Error", e.toString(), [{ text: "OK", onPress: () => null }]);
  }
};

function HomeScreen({ navigation }) {
  const markedDates = {
    "2023-02-01": { marked: true, dotColor: "red" },
  };
  return (
    <SafeAreaProvider>
      <View>
        <Calendar
          markedDates={markedDates}
          onDayPress={async (day) => {
            const selectedDate = day.dateString;
            await savereturndate(selectedDate);
            navigation.push("Detail");
          }}
        />
      </View>
    </SafeAreaProvider>
  );
}

export default HomeScreen;

2. 修正Detail.js的渲染逻辑

  • 使用useState和useEffect钩子,实现数据读取后自动更新页面
  • 处理AsyncStorage返回null的情况

修改后的Detail.js:

import React, { useState, useEffect } from "react";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { View, Text, Alert } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";

function DetailScreen() {
  const [selectedDate, setSelectedDate] = useState("");

  useEffect(() => {
    const getreturndate = async () => {
      try {
        const date = await AsyncStorage.getItem("selectdate");
        if (date) {
          setSelectedDate(date);
        }
      } catch (e) {
        Alert.alert("Error", e.toString(), [{ text: "OK", onPress: () => null }]);
      }
    };
    getreturndate();
  }, []);

  return (
    <SafeAreaProvider>
      <View>
        <Text>{selectedDate || "未选择日期"}</Text>
      </View>
    </SafeAreaProvider>
  );
}

export default DetailScreen;

3. 更优方案:直接通过路由传参

无需依赖AsyncStorage,React Navigation支持跳转时直接传递参数,完全避免异步延迟问题:

Home.js修改跳转逻辑:

onDayPress={(day) => {
  navigation.push("Detail", { selectedDate: day.dateString });
}}

Detail.js接收参数:

function DetailScreen({ route }) {
  const { selectedDate } = route.params || {};
  return (
    <SafeAreaProvider>
      <View>
        <Text>{selectedDate || "未选择日期"}</Text>
      </View>
    </SafeAreaProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:16:23