React函数组件中如何根据数值涨跌设置数字背景色?
问题分析与修复
你的组件核心思路没问题,但两处关键问题导致功能失效:
- useEffect依赖错误:把
prevValue加入依赖数组后,每次调用setPrevValue都会触发useEffect重新执行,导致prevValue更新时机混乱,无法正确对比新旧数值。 - 定时器竞态问题:如果数值在1秒内多次变化,旧定时器未完成就被新的覆盖,会导致背景色停留在错误状态。
修复后的代码
import React, { useState, useEffect, useRef } from 'react' const FlashNumber = ({ value }) => { const [bgColor, setBgColor] = useState('white') const prevValueRef = useRef(null) const timeoutRef = useRef(null) useEffect(() => { // 清理之前的定时器,避免竞态干扰 if (timeoutRef.current) { clearTimeout(timeoutRef.current) } // 首次渲染只初始化历史值,不触发颜色变化 if (prevValueRef.current !== null) { if (value > prevValueRef.current) { setBgColor('green') } else if (value < prevValueRef.current) { setBgColor('red') } // 1秒后恢复默认背景色 timeoutRef.current = setTimeout(() => { setBgColor('white') }, 1000) } // 更新历史值 prevValueRef.current = value // 组件卸载或依赖变化时清理定时器 return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) } } }, [value]) return <div style={{ backgroundColor: bgColor }}>{value}</div> } export default FlashNumber
关键改动说明
- 用
useRef保存历史值:useRef的更新不会触发组件重渲染,避免了原代码中useEffect重复执行的问题,能稳定存储上一次的数值。 - 定时器生命周期管理:每次执行逻辑前清理旧定时器,组件卸载时也清理定时器,既避免竞态问题,也防止内存泄漏。
- 简化依赖数组:只保留
value作为依赖,确保只有传入的数值变化时才执行对比逻辑。
内容的提问来源于stack exchange,提问作者cjm2671
相关产品推荐
相关产品推荐

