如何在.map()渲染的div列表中为特定按钮设置一段时间禁用
解决方案
核心思路是使用对象类型的状态存储每个角色对应冷却到期时间,搭配本地存储做持久化,实现单按钮独立禁用,不会互相影响。
步骤1:定义冷却状态与持久化逻辑
在组件内添加如下状态和副作用逻辑:
import { useState, useEffect } from 'react'; // 组件内代码 // 初始化时从本地存储读取已有的冷却记录 const [coolDowns, setCoolDowns] = useState(() => { const savedCoolDowns = localStorage.getItem('battle_cool_downs'); return savedCoolDowns ? JSON.parse(savedCoolDowns) : {}; }); // 冷却状态变化时自动同步到本地存储,刷新页面不失效 useEffect(() => { localStorage.setItem('battle_cool_downs', JSON.stringify(coolDowns)); }, [coolDowns]);
步骤2:封装按钮点击逻辑
封装点击处理函数,点击时自动为当前角色设置24小时冷却:
const handleBattleClick = (chrKey) => { // 前置判断,防止冷却期间重复触发 if (Date.now() < (coolDowns[chrKey] || 0)) return; // 调用你原有打开弹窗的逻辑 openModal(chrKey); // 记录当前角色冷却到期时间:当前时间+24小时毫秒数 setCoolDowns(prev => ({ ...prev, [chrKey]: Date.now() + 24 * 60 * 60 * 1000 })); };
步骤3:修改渲染逻辑中的按钮配置
调整map循环内的按钮代码,添加禁用状态判断:
<button className="btn btn-danger my-1" value={key} onClick={() => handleBattleClick(key)} disabled={Date.now() < (coolDowns[key] || 0)} > {Date.now() < (coolDowns[key] || 0) ? '冷却中' : 'Battle!'} </button>
注意:你原有代码中
onClick={openModal(key)}的写法是错误的,会在组件渲染时直接执行所有openModal逻辑,必须用箭头函数包裹才能实现点击触发。
优化建议
建议你将map循环的索引key替换为角色自身的唯一标识(比如链上生成的角色ID),避免角色数组顺序变化时,冷却状态和角色对应错误。
内容的提问来源于stack exchange,提问作者TolgaKmbl
相关产品推荐
相关产品推荐

