游戏历史徽章更新时初始颜色闪烁异常求助
问题:游戏历史徽章颜色闪烁异常
我正在开发一款游戏,顶部展示最近4局游戏结果的历史徽章,规则为:若数值大于multiplier(投注金额的乘数)则徽章设为绿色,否则为红色。但每次更新新数据时,徽章会先显示红色,闪烁数毫秒后才变为绿色,这属于异常行为。
当前代码
const Badge = ({ multiplierList, setIdx, setMultiplierList, setShow, loadedData }) => { const { isWinningSound, setColorSetter, colorSetter } = useGameContext() const getButtonColor = (value) => { const entry = loadedData?.find(data => data?.final_multiplier === value); if (entry) { if (multiplierList.length > 4) { const tempList = [...multiplierList] tempList.shift() setMultiplierList(tempList) } return entry?.status === "over" ? "red" : "green"; } }; return ( <div className='history'> <div className='d-flex badge'>{ multiplierList.map((value, index) => ( <div className='mx-2' key={index}> {value && <button onClick={handleShow} value={value} className="badge rounded-4 text-black " style={{ backgroundColor: getButtonColor(value), fontSize: "1rem" }}> {value}x </button>} </div> )) }</div> </div> ); }
问题原因及修复方案
核心问题
- 样式函数中混入状态修改:
getButtonColor是计算背景色的纯逻辑函数,却在内部调用setMultiplierList修改状态,每次渲染都会触发状态更新,引发组件反复重渲染,同时导致数据不同步。 - 未处理数据未匹配的情况:当
loadedData未更新完成时,entry会是undefined,此时getButtonColor无返回值,背景色会使用默认样式(大概率为红色),等loadedData就绪后才返回正确绿色,从而产生闪烁。 handleShow函数未定义:代码中使用了onClick={handleShow}但未声明该函数,会引发控制台报错。
修复步骤
将列表长度维护移至
useEffect:
监听multiplierList变化,自动截断超长列表,避免在样式函数中处理状态:import { useEffect } from 'react'; const Badge = ({ multiplierList, setIdx, setMultiplierList, setShow, loadedData }) => { // ...其他代码 useEffect(() => { if (multiplierList.length > 4) { // 移除最早的一条记录,保持最多4条 setMultiplierList(prevList => prevList.slice(1)); } }, [multiplierList, setMultiplierList]); // ...其他代码 }优化
getButtonColor函数:
移除状态修改逻辑,同时处理entry不存在的情况,避免默认颜色导致的闪烁:const getButtonColor = (value) => { const entry = loadedData?.find(data => data?.final_multiplier === value); // 当数据未匹配时,返回占位色(如透明或灰色),而非依赖默认样式 if (!entry) return 'transparent'; return entry.status === "over" ? "red" : "green"; };确保数据同步:
只有当loadedData完全就绪后,再更新multiplierList,避免出现列表已有值但对应数据未加载完成的情况。补全或移除
handleShow函数:
如果需要点击徽章触发逻辑,补全handleShow的定义;如果不需要,直接移除onClick属性。
内容的提问来源于stack exchange,提问作者Lokendra Singh Rathore
相关产品推荐
相关产品推荐

