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
相关产品推荐
相关产品推荐

