如何在react-native-calendars中实现年份选择功能?
解决react-native-calendars年份选择后需关闭重开才生效的问题
问题根源在于两处:冗余的useEffect引发无效渲染循环,以及react-native-calendars的Calendar组件未触发即时视图更新。
修复步骤:
移除无效的useEffect
你代码中这段useEffect完全多余,还会导致无限渲染循环,直接删除:useEffect(() => { setCurrentYear(prevYear => { return prevYear }) }, [currentYear])给Calendar组件添加key属性
给NativeCalendar添加key={currentYear},当currentYear变化时,React会重新挂载组件,立即切换到选中的年份。
修改后的完整代码:
import { theme } from "@/Common/theme" import React, { useState } from "react" import { Modal, Text, TouchableOpacity, View } from "react-native" import { Calendar as NativeCalendar } from "react-native-calendars" import ModalSelector from "react-native-modal-selector" import { useCalendar } from "./useCalendar" export interface CalendarProps { visible: boolean onClose: () => void onChange: (value: string) => void value?: string } export const Calendar = (props: CalendarProps): JSX.Element => { const { visible, styles, onClose, markedDate, onMarkedDateChange, rest } = useCalendar(props) const [selectedYear, setSelectedYear] = useState("") const [currentYear, setCurrentYear] = useState( new Date().getFullYear().toString() ) const renderYearSelector = () => { const years = Array.from({ length: 100 }, (_, index) => { const currentYear = new Date().getFullYear() return { label: `${currentYear - index}`, key: index.toString() } }) return ( <ModalSelector data={years} initValue="Seleccione el año" onChange={option => { setSelectedYear(option.label) setCurrentYear(option.label) }} /> ) } return ( <Modal visible={visible} animationType="fade" transparent {...rest}> <View style={styles.viewCalendar}> <View style={styles.calendarContainer}> <View style={styles.calendarHeader}> <Text style={{ color: theme.colors.WHITE }}> Seleccionar fecha </Text> <Text style={styles.selectDate}> {markedDate && markedDate !== "" ? new Date(markedDate).toLocaleDateString( "es-CO", { day: "2-digit", weekday: "short", month: "short", } ) : new Date().toLocaleDateString("es-CO", { day: "2-digit", weekday: "short", month: "short", })} </Text> </View> {renderYearSelector()} <NativeCalendar key={currentYear} theme={{ calendarBackground: "transparent", }} onDayPress={(date: { dateString: string }) => onMarkedDateChange(date.dateString) } markedDates={{ [markedDate]: { selected: true, color: theme.colors.SECONDARY, }, }} current={`${currentYear}-01-01`} /> <View style={styles.buttonscontainer}> <TouchableOpacity onPress={onClose}> <Text style={styles.cancel}>CANCELAR</Text> </TouchableOpacity> <TouchableOpacity onPress={onClose}> <Text style={styles.accept}>ACEPTAR</Text> </TouchableOpacity> </View> </View> </View> </Modal> ) }
原理说明:
react-native-calendars的Calendar组件内部未监听current属性变化来触发视图更新,通过添加key={currentYear},当年份改变时,React会识别为新组件并重新渲染,直接加载对应年份的日历视图,无需关闭重开Modal即可即时生效。
内容的提问来源于stack exchange,提问作者Sebastian Casadiego
相关产品推荐
相关产品推荐

