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

React中如何基于商品剩余时间触发弹窗?解决map内无法用useEffect问题

问题描述

我有一组需要单独监控剩余时间的商品列表:

const products = [{
    itemID: 1,
    name: 2,
    remainingTime: 600
},
{
    itemID: 12,
    name: 333,
    remainingTime: 300,
}]

想要在任意商品的剩余时间≤100秒时弹出提示框,尝试了以下实现方式:

products.map((product) => {
    let remainingTime = product.remainingTime;
    useEffect(() => {
        if (remainingTime <= 100){
            addPopup("Time Expiring")
        }
    }, [remainingTime])
})

但React不允许在map回调中使用useEffect,求合适的实现方法。

解决方案

方法1:在组件顶层统一监控

直接在组件的顶层useEffect里遍历商品列表,同时记录已提示的商品ID避免重复弹窗:

import { useEffect, useState } from 'react';

function ProductMonitor() {
    const products = [{/* 你的商品数据 */}];
    const [notifiedItems, setNotifiedItems] = useState(new Set());

    useEffect(() => {
        products.forEach(product => {
            if (product.remainingTime <= 100 && !notifiedItems.has(product.itemID)) {
                addPopup(`商品${product.name}即将过期`);
                setNotifiedItems(prev => new Set([...prev, product.itemID]));
            }
        });
    }, [products, notifiedItems]);

    return (
        <div>
            {products.map(product => (
                <div key={product.itemID}>
                    {product.name} - 剩余时间:{product.remainingTime}秒
                </div>
            ))}
        </div>
    );
}

方法2:拆分为子组件维护独立逻辑

把单个商品的监控和展示封装成子组件,在子组件内部合法使用useEffect:

import { useEffect, useState } from 'react';

// 单个商品组件
function ProductItem({ product }) {
    const [hasNotified, setHasNotified] = useState(false);

    useEffect(() => {
        if (product.remainingTime <= 100 && !hasNotified) {
            addPopup(`商品${product.name}即将过期`);
            setHasNotified(true);
        }
    }, [product.remainingTime, hasNotified]);

    return (
        <div>
            {product.name} - 剩余时间:{product.remainingTime}秒
        </div>
    );
}

// 商品列表父组件
function ProductList() {
    const products = [{/* 你的商品数据 */}];

    return (
        <div>
            {products.map(product => (
                <ProductItem key={product.itemID} product={product} />
            ))}
        </div>
    );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:35:30