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

React Native应用动态日期时间刷新代码的放置与实现方法

解决方案:实现基于Firestore日期的动态时间差显示与自动刷新

修正原有代码的关键错误

你的原有代码中useEffect使用了async回调,这会触发React警告——async函数返回Promise,无法作为有效的清理函数。需去掉async,onSnapshot无需await,直接使用即可。


步骤1:完善Firestore数据获取,添加日期字段

首先要从Firestore文档中读取date字段,在快照处理逻辑中补充该字段:

// 在querySnapshot的forEach循环内
const { price, new_price, food_name, restaurant, piece, img, date } = doc.data()
users.push({
    id: doc.id,
    price,
    new_price,
    food_name,
    restaurant,
    piece,
    img,
    date // 新增日期字段
})

步骤2:编写时间差格式化函数

创建工具函数,将Firestore返回的Timestamp类型日期转为时间戳,再计算与当前时间的差值,输出友好文本:

const formatTimeDifference = (firestoreDate) => {
    // 将Firestore Timestamp转为毫秒级时间戳
    const itemTime = firestoreDate.toDate().getTime();
    const now = Date.now();
    const diffInMs = now - itemTime;
    const diffInMinutes = Math.floor(diffInMs / (1000 * 60));

    if (diffInMinutes < 1) return '刚刚';
    if (diffInMinutes === 1) return '1分钟前';
    return `${diffInMinutes}分钟前`;
};

步骤3:实现每分钟自动刷新

通过状态触发组件重新渲染,配合定时器保证时间差文本每分钟更新:

const Homepage = () => {
    const [users, setUsers] = useState([]);
    const [refreshTrigger, setRefreshTrigger] = useState(0); // 触发刷新的状态标记
    const todoRef = firebase.firestore().collection('Data');

    // 每分钟更新状态标记,强制组件重新计算时间差
    useEffect(() => {
        const interval = setInterval(() => {
            setRefreshTrigger(prev => prev + 1);
        }, 60000); // 60秒 = 1分钟

        // 组件卸载时清理定时器,避免内存泄漏
        return () => clearInterval(interval);
    }, []);

    // Firestore快照监听逻辑(修正async错误)
    useEffect(() => {
        const unsubscribe = todoRef.onSnapshot(querySnapshot => {
            const users = [];
            querySnapshot.forEach((doc) => {
                const { price, new_price, food_name, restaurant, piece, img, date } = doc.data();
                users.push({
                    id: doc.id,
                    price,
                    new_price,
                    food_name,
                    restaurant,
                    piece,
                    img,
                    date
                });
            });
            setUsers(users);
        });

        // 清理快照监听
        return () => unsubscribe();
    }, []);

    // ... 其他代码
}

步骤4:在FlatList中渲染动态时间差文本

在renderItem中调用格式化函数,添加时间差显示:

<FlatList
    style={{height:'100%'}}
    data={users}
    numColumns={1}
    renderItem={({item}) => (
        <Pressable style={styles.container}>
            <View style={styles.innerContainer}>
                <View style={styles.box}>
                    <Text style={styles.itemFood}>{item.food_name}</Text>
                    <Text style={styles.itemRestaurant}>{item.restaurant}</Text>
                    <Text style={styles.itemPrice}>{item.price}</Text>
                    <Text style={styles.itemPiece}>{item.piece}</Text>
                    <Text style={styles.itemNew}>{item.new_price}</Text>
                    {/* 新增动态时间差文本 */}
                    <Text style={styles.itemTime}>{formatTimeDifference(item.date)}</Text>
                    <Image style={styles.itemİmg} source={{ uri: item.img }} />
                </View>
            </View>
        </Pressable>
    )}
/>

步骤5:补充时间文本样式

在StyleSheet.create中添加时间文本的样式:

itemTime:{
    position: 'absolute',
    bottom: 10,
    right: 10,
    fontSize: 12,
    color: '#666'
}

核心注意事项

  • Firestore日期处理:Firestore返回的date是Timestamp类型,必须通过toDate()转换为JS Date对象后再获取时间戳,否则计算会出错。
  • 资源清理:必须在组件卸载时清除定时器和Firestore快照监听,避免内存泄漏。
  • 性能优化:时间差计算放在组件内部,依赖refreshTrigger更新触发重新计算,保证显示最新数据的同时避免不必要的重复渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:38:10