You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React实现随机数滚动动画并与用户输入值对比的最佳方案

问题根因分析
  • 你写的判断逻辑执行时机错误:handleGenerateNumber 里的if判断是点击按钮瞬间执行的,此时5秒的随机数滚动还没开始,对比的是点击前的旧随机数,自然不会触发预期逻辑
  • React状态更新为异步批量处理:调用setToggle、setRandomNumber之后,无法立即读取到最新的状态值,必须在状态更新完成后的钩子/回调中才能拿到最新值
  • 额外注意:如果你的输入值是从<input />表单获取的,默认是字符串类型,直接用===和数字类型的随机数对比会因为类型不一致判定不相等,需要先做类型转换
修正后的实现方案

核心逻辑:新增useEffect监听toggle状态,当toggle从true变为false时,说明5秒滚动已经停止,此时再执行两个数值的对比逻辑即可。

import { useState, useEffect } from 'react';

export default function RandomRoll() {
  const [randomNumber, setRandomNumber] = useState(0);
  const [toggle, setToggle] = useState(false);
  const [inputNum, setInputNum] = useState(0);

  // 控制随机数滚动逻辑
  useEffect(() => {
    let counter;
    if (toggle) {
      counter = setInterval(
        () => setRandomNumber(Math.floor(Math.random() * 10)),
        50
      );
    }
    return () => {
      clearInterval(counter);
    };
  }, [toggle]);

  // 监听滚动停止事件,执行结果对比
  useEffect(() => {
    // 仅当滚动从开启变为关闭时执行判断
    if (!toggle) {
      if (inputNum === randomNumber) {
        console.log(randomNumber, "you won");
        // 此处可添加自定义中奖逻辑
      }
    }
  }, [toggle, inputNum, randomNumber]);

  const handleGenerateNumber = () => {
    setToggle(true);
    // 5秒后停止滚动
    setTimeout(() => {
      setToggle(false);
    }, 5000);
  };

  // 输入框绑定逻辑
  const handleInputChange = (e) => {
    // 直接转成数字存储,避免后续类型判断问题
    setInputNum(Number(e.target.value));
  };

  return (
    <div>
      <input type="number" min="0" max="9" onChange={handleInputChange} value={inputNum} />
      <div>当前随机数:{randomNumber}</div>
      <button onClick={handleGenerateNumber} disabled={toggle}>开始抽奖</button>
    </div>
  )
}
核心修改说明
  • 新增了专门监听滚动停止的useEffect,依赖项包含toggle、inputNum、randomNumber,保证判断时拿到的都是最新值
  • 输入框取值时直接转换为数字类型,避免类型不一致导致的判断失败
  • 给按钮加了disabled状态,避免滚动过程中重复点击触发多次定时器

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 03:00:00