如何在React中实现每秒自动累加多个数值?
解决方案
核心实现思路
- 用状态管理各团队的员工数量,支持动态扩展团队类型
- 通过
useEffect设置每秒定时器,计算所有员工的总自动收益并更新分数 - 实现员工雇佣逻辑,确保分数足够时才能雇佣,且可灵活分配员工到对应团队
修改后的完整代码
import React, { useState, useEffect } from 'react' const App = () => { // ====================================== // HOOKS // ====================================== const [score, setScore] = useState(0) const [showEZBake, setShowEZBake] = useState(false) const [showToasterOven, setShowToasterOven] = useState(false) const [showConvectionOven, setShowConvectionOven] = useState(false) const [showSmallFactory, setShowSmallFactory] = useState(false) // 管理各团队员工数量,key为团队标识,value为员工数,方便扩展新团队 const [employeeTeams, setEmployeeTeams] = useState({ '$1团队': 0, '$5团队': 0 }) // 定义各团队的每秒收益值,与员工队伍对应 const teamEarnings = { '$1团队': 1, '$5团队': 5 } // 雇佣单个员工的成本 const employeeCost = 10 // ====================================== // FUNCTIONS // ====================================== const winCondition = () => { if (score >= 100000) { return ( <h1>YOURE A WINNER!!</h1> ) } } // EARN REVENUE FUNCTIONS const earn1 = () => { setScore(prev => prev + 1) } const earn5 = () => { setScore(prev => prev + 5) } const earn25 = () => { setScore(prev => prev + 25) } const earn50 = () => { setScore(prev => prev + 50) } const earn250 = () => { setScore(prev => prev + 250) } // PURCHASE ITEMS FUNCTIONS const buyEZOven = () => { setScore(prev => prev - 25) } const buyToasterOven = () => { setScore(prev => prev - 250) } const buyConvectionOven = () => { setScore(prev => prev - 1000) } const buySmallFactory = () => { setScore(prev => prev - 15000) } const upgradeEZOven = () => { if (score >= 25) { setShowEZBake(true) buyEZOven() } } const upgradeToasterOven = () => { if (score >= 250 ) { setShowToasterOven(true) buyToasterOven() } } const upgradeConvectionOven = () => { if (score >= 1000) { setShowConvectionOven(true) buyConvectionOven() } } const upgradeSmallFactory = () => { if (score >= 15000) { setShowSmallFactory(true) buySmallFactory() } } // 雇佣员工到指定团队 const hireEmployee = (team) => { if (score >= employeeCost) { setScore(prev => prev - employeeCost) setEmployeeTeams(prev => ({ ...prev, [team]: prev[team] + 1 })) } } // ====================================== // AUTO EARNING // ====================================== useEffect(() => { // 每秒计算所有员工的总收益 const interval = setInterval(() => { let totalAutoEarn = 0 Object.keys(employeeTeams).forEach(team => { totalAutoEarn += employeeTeams[team] * teamEarnings[team] }) if (totalAutoEarn > 0) { setScore(prev => prev + totalAutoEarn) } }, 1000) // 组件卸载时清理定时器 return () => clearInterval(interval) }, [employeeTeams]) // ====================================== // DISPLAY // ====================================== return ( <div style={{ padding: '20px' }}> <h1>Bakery</h1> <h2>Revenue ${score}</h2> <h3>No Bake Pudding</h3><button onClick={earn1}>+$1</button> {/* EZ BAKE OVEN */} {showEZBake ? ( <> <h3>Easy Bake Oven</h3> <button onClick={earn5}>+$5</button> </> ) : ( <> <h3>Purchase Easy Bake Oven</h3> <button onClick={upgradeEZOven}>-$25</button> </> ) } {/* TOASTER OVEN */} {showToasterOven ? ( <> <h3>Toaster Oven</h3> <button onClick={earn25}>+$25</button> </> ) : ( <> <h3>Purchase Toaster Oven</h3> <button onClick={upgradeToasterOven}>-$250</button> </> )} {/* CONVECTION OVEN */} {showConvectionOven ? ( <> <h3>Convection Oven</h3> <button onClick={earn50}>+$50</button> </> ) : ( <> <h3>Purchase Convection Oven</h3> <button onClick={upgradeConvectionOven}>-$1000</button> </> )} {/* FACTORY */} {showSmallFactory ? ( <> <h3>Small Factory Production</h3> <button onClick={earn250}>+$250</button> </> ) : ( <> <h3>Purchase Small Factory</h3> <button onClick={upgradeSmallFactory}>-$15,000</button> </> )} {/* 员工雇佣区域 */} <div style={{ marginTop: '30px', borderTop: '1px solid #ccc', paddingTop: '20px' }}> <h2>员工管理</h2> {Object.keys(employeeTeams).map(team => ( <div key={team} style={{ margin: '10px 0' }}> <h3>{team}:{employeeTeams[team]}名员工(每秒+${employeeTeams[team] * teamEarnings[team]})</h3> <button onClick={() => hireEmployee(team)} disabled={score < employeeCost}> 雇佣1名员工(成本${employeeCost}) </button> </div> ))} </div> {/* WIN CONDITION */} {winCondition()} </div> ) } export default App
关键部分说明
- 动态扩展支持:
employeeTeams和teamEarnings采用键值对结构,新增团队只需在两个对象中添加对应项即可,无需修改核心逻辑。 - 自动收益计算:每秒遍历所有团队,累加员工数×对应团队收益的总和,确保多员工效果叠加(如2名$1团队员工+1名$5团队员工,每秒总收益为7)。
- 状态更新优化:所有分数更新使用函数式写法(
setScore(prev => prev + ...)),避免闭包导致的状态更新错误。 - 用户体验优化:雇佣按钮在分数不足时自动禁用,同时实时显示各团队的当前收益贡献。
内容的提问来源于stack exchange,提问作者user18197093
相关产品推荐
相关产品推荐

