sử dụng useRef để đến index là năm hiện tại trong list import React, {useCallback, useMemo, useState} from 'react';
import {FlatList, SafeAreaView, StyleSheet, Text, View} from 'react-native';

const Test = () => {
  const currentYear = new Date().getFullYear();
  const yearList = useMemo(() => {
    const arr = [];
    for (let i = -50; i < 50; i++) {
      arr.push({year: currentYear + i});
    }
    return arr;
  }, [currentYear]);

  const monthList = useMemo(
    () => [
      {name: 'January', days: 31},
      {name: 'February', days: 28},
      {name: 'March', days: 31},
      {name: 'April', days: 30},
      {name: 'May', days: 31},
      {name: 'June', days: 30},
      {name: 'July', days: 31},
      {name: 'August', days: 31},
      {name: 'September', days: 30},
      {name: 'October', days: 31},
      {name: 'November', days: 30},
      {name: 'December', days: 31},
    ],
    [],
  );

  const daysInMonth = useCallback((year, month) => {
    if (month === 2) {
      if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
        return 29;
      } else {
        return 28;
      }
    }
    return [4, 6, 9, 11].includes(month) ? 30 : 31;
  }, []);

  const isCurrentDate = useCallback((year, month, i) => {
    const currentDate = new Date();
    return year === currentDate.getFullYear() && month - 1 === currentDate.getMonth() && i === currentDate.getDate();
  }, []);

  const MonthList = React.memo(({year, month}) => {
    const firstDay = new Date(year.year, month.month - 1, 1).getDay();
    const daysInMonthCount = daysInMonth(year.year, month.month);
    const days = useMemo(() => {
      const arr = [];
      for (let i = 1; i <= firstDay; i++) {
        arr.push(<View key={`empty-${i}`} style={[styles.day, styles.emptyDay]} />);
      }

      for (let i = 1; i <= daysInMonthCount; i++) {
        arr.push(
          <View key={i} style={styles.day}>
            <Text style={[styles.dayText, isCurrentDate(year.year, month.month, i) && styles.red]}>{i}</Text>
          </View>,
        );
      }
      return arr;
    }, [year, month, firstDay, daysInMonthCount, isCurrentDate]);

    const isCurrentMonth = year.year === new Date().getFullYear() && month.month - 1 === new Date().getMonth();

    return (
      <View style={styles.month}>
        <Text style={[styles.monthName, isCurrentMonth && styles.red]}>{month.name}</Text>
        <View style={styles.days}>{days}</View>
      </View>
    );
  });

  const YearList = React.memo(({year}) => {
    const monthData = monthList.map((month, index) => ({...month, month: index + 1}));
    const isCurrentYear = year.year === new Date().getFullYear();
    return (
      <View>
        <Text style={[styles.title, isCurrentYear && styles.red]}>{year.year}</Text>
        <View style={styles.line} />
        <View style={styles.monthsContainer}>
          {monthData.map((month, index) => (
            <MonthList key={index} month={month} year={year} />
          ))}
        </View>
      </View>
    );
  });

  return (
    <SafeAreaView style={styles.container}>
      <FlatList data={yearList} renderItem={({item}) => <YearList year={item} />} keyExtractor={(item, index) => `${item.year}-${index}`} />
    </SafeAreaView>
  );
};

export default Test;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 30,
    fontWeight: 'bold',
    marginBottom: 5,
    marginLeft: 15,
  },
  line: {
    backgroundColor: 'grey',
    height: 0.5,
    opacity: 0.5,
    marginBottom: 20,
  },
  monthsContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-between',
  },
  month: {
    width: '33%',
    marginBottom: 10,
  },
  monthName: {
    fontSize: 18,
    fontWeight: 'bold',
    marginBottom: 10,
    marginLeft: 5,
  },
  days: {
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
  day: {
    flexBasis: '14%',
    height: 20,
    width: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },

  dayText: {
    fontSize: 10,
    fontWeight: '600',
  },
  emptyDay: {
    backgroundColor: 'transparent',
    borderWidth: 0,
  },
  red: {
    color: 'red',
  },
});