React Native FlatList多时区会议数据展示实现求助
解决React Native FlatList多时区会议筛选与展示问题
核心问题修正
你提到的getTzHour只执行一次,本质是过滤逻辑未对每条会议数据单独调用时区转换函数,而是提前计算了固定值。以下是完整的落地方案:
1. 获取用户本地时区
直接通过原生API获取:
const userTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; // 示例输出:'Asia/Shanghai'
2. 封装时区转换与筛选工具函数
推荐轻量库date-fns-tz处理时区转换,先安装依赖:
npm install date-fns date-fns-tz
封装单条会议数据的处理函数:
import { parseISO, formatInTimeZone, startOfDay, endOfDay, addHours } from 'date-fns-tz'; // 处理单条会议,返回转换后的本地时间及筛选状态 const processMeeting = (meeting, userTz) => { // 假设会议时间为带时区的ISO格式,如'2024-05-20T14:00:00+08:00' const meetingDate = parseISO(meeting.startTime); // 转换为用户本地时间 const localStartTime = formatInTimeZone(meetingDate, userTz, 'yyyy-MM-dd HH:mm:ss'); const localStartDateObj = parseISO(localStartTime); // 计算用户本地当日起止、未来1小时时间点 const todayStart = startOfDay(new Date()); const todayEnd = endOfDay(new Date()); const oneHourLater = addHours(new Date(), 1); // 判断是否符合筛选条件 const isTodayMeeting = localStartDateObj >= todayStart && localStartDateObj <= todayEnd; const isWithinNextHour = localStartDateObj >= new Date() && localStartDateObj <= oneHourLater; return { ...meeting, localStartTime, isTodayMeeting, isWithinNextHour }; };
3. 批量处理与筛选数据
对7000条数据批量转换后筛选:
// 假设原始会议数组为meetingsData const processedMeetings = meetingsData.map(meeting => processMeeting(meeting, userTimeZone)); // 筛选当日且未来1小时内的会议 const filteredMeetings = processedMeetings.filter(meeting => meeting.isTodayMeeting && meeting.isWithinNextHour);
4. FlatList展示处理后的数据
直接传入筛选后的数组渲染:
import { FlatList, Text, View } from 'react-native'; // 组件内渲染部分 <FlatList data={filteredMeetings} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={{ padding: 16, borderBottomWidth: 1, borderBottomColor: '#eee' }}> <Text style={{ fontSize: 16, fontWeight: 'bold' }}>{item.title}</Text> <Text>本地开始时间:{item.localStartTime}</Text> <Text>原始时区:{item.timeZone}</Text> </View> )} />
性能优化建议
针对7000条数据的场景,用useMemo缓存处理结果避免重复计算:
import { useMemo } from 'react'; // 组件内缓存筛选结果 const filteredMeetings = useMemo(() => { return meetingsData .map(meeting => processMeeting(meeting, userTimeZone)) .filter(meeting => meeting.isTodayMeeting && meeting.isWithinNextHour); }, [meetingsData, userTimeZone]);
无第三方库替代方案
若不想依赖外部库,用原生Intl API实现转换:
const processMeetingWithoutLib = (meeting, userTz) => { const meetingDate = new Date(meeting.startTime); // 转换为用户本地时间字符串 const localStartTime = new Intl.DateTimeFormat('zh-CN', { timeZone: userTz, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }).format(meetingDate); // 后续筛选逻辑与之前一致 const localStartDateObj = new Date(localStartTime); // ... };
内容的提问来源于stack exchange,提问作者Learner-Driver
相关产品推荐
相关产品推荐

