USER
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',
},
});ASSISTANT
To use useRef to reach the index of the current year in the imported list, you can add a useRef hook and set its initial value to 0. Then, in the FlatList's renderItem function, you can use the index parameter to compare with the value of the useRef hook and set its value accordingly. Here is an example:
import React, {useCallback, useMemo, useState, useRef} 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();
const currentIndexRef = useRef(0);
return (
<View>
<Text style={[styles.title, isCurrentYear && styles.red]}>{year.year}</Text>
<View style={styles.line} />
<View style={styles.monthsContainer}>
{monthData.map((month, index) => {
if (year.year === currentYear && index === new Date().getMonth()) {
currentIndexRef.current = index;
}
return <MonthList key={index} month={month} year={year} />;
})}
</View>
{currentIndexRef.current === new Date().getMonth() && <Text>This is the current year and month!</Text>}
</View>
);
});
return (
<SafeAreaView style={styles.container}>
<FlatList
data={yearList}
renderItem={({item, index}) => <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',
},
});