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

React Native Calendars组件日历标记点颜色显示异常求助

React Native Calendar 标记点颜色异常问题修复

问题原因

  • 直接修改dates状态数组(dates.push(date)),React无法检测到数组引用变化,且状态更新异步,循环中始终获取旧数组值
  • 循环内每次通过dates.reduce生成新对象并调用setMarkedDates,但因dates未正确更新,所有已添加日期会被重置为当前循环的颜色
  • 多次调用setMarkedDates会被React合并,最终仅保留最后一次的状态值

修复后的代码

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

function HomeScreen({navigation}) {
  const [markedDates, setMarkedDates] = React.useState({});

  // 颜色映射表,简化逻辑
  const colorMap = {
    'happy-pink': 'pink',
    'happy2-pink': 'pink',
    'happy-yellow': 'yellow',
    'sad-skyblue': 'skyblue',
    'soso-green': 'green',
    'soso-orange': 'orange'
  };

  const readCalendarData = async () => {
    try {
      const listnumber = await AsyncStorage.getItem("listnumber");
      const listnumbertoint = parseInt(listnumber, 10);
      // 用临时对象收集所有日期的标记信息,避免依赖状态
      const tempMarkedDates = {};

      for (let i = 1; i <= listnumbertoint; i++) {
        const date = await AsyncStorage.getItem(i + "calendar");
        if (!date) continue; // 避免空日期导致错误
        const colorKey = await AsyncStorage.getItem(date + "calendar");
        // 获取对应颜色,默认粉色
        const dotColor = colorMap[colorKey] || 'pink';
        
        // 直接给临时对象添加日期标记
        tempMarkedDates[date] = { marked: true, dotColor };
      }

      // 一次性设置所有标记日期
      setMarkedDates(tempMarkedDates);
    } catch (error) {
      console.error(error);
    }
  };

  useEffect(() => {
    readCalendarData();
  }, [])

  return(
      <SafeAreaProvider>
         <View>
            <Calendar
              markedDates={markedDates}
              onDayPress={(day) => {
                navigation.push('Detail', {day});
              }}
           />
         </View>
      </SafeAreaProvider>
  );
}

export default HomeScreen;

关键优化点

  • 使用**临时对象tempMarkedDates**收集所有日期的标记信息,避免依赖异步的状态更新
  • 用colorMap对象替代重复的if-else判断,简化代码逻辑
  • 仅在循环结束后一次性调用setMarkedDates,确保所有日期的颜色都被正确设置
  • 添加空值判断,避免因date为空导致的潜在错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:55:00