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

React状态变更时组件无法更新问题求助

问题:更新videoId状态后组件未更新

尝试通过state更新videoId,但状态变更后组件并未更新。试过展开新数据,也无效。

原代码

const exercises = [
  {
    id: 1,
    videoSrc: video,
  },
  {
    id: 2,
    videoSrc: video
  },
  {
    id: 3,
    videoSrc: video
  },
  {
    id: 4,
    videoSrc: video
  },
];

export function WarmUpContent() {
  const [videoId, setVideoId] = useState(1);
  const [videoSrc, setVideoSrc] = useState(exercises[0].videoSrc);

  function handleNext() {
    setVideoId(videoId + 1);
    console.log(videoId);

    const result = exercises.find(({ id }) => id === videoId);
    const video = result.videoSrc;
    setVideoSrc([...video]);
  }

  return (
    <>
      <div className="">
        <div className="mb-4">
          <VideoPlayer src={videoSrc} />
        </div>
        <div className="">          
          <Button onClick={() => handleNext()} size="slim">
            Next
          </Button>
        </div>
      </div>
    </>
  );
}

问题原因

  1. useState异步特性:调用setVideoId(videoId + 1)后,videoId不会立即更新,后续用旧的videoId查找exercise,导致videoSrc更新错误。
  2. 冗余状态维护:同时维护videoId和videoSrc两个状态,容易出现不同步;若video不是数组,[...video]的写法会报错或无效。

修复方案

优化后的代码

const exercises = [
  {
    id: 1,
    videoSrc: video,
  },
  {
    id: 2,
    videoSrc: video
  },
  {
    id: 3,
    videoSrc: video
  },
  {
    id: 4,
    videoSrc: video
  },
];

export function WarmUpContent() {
  const [videoId, setVideoId] = useState(1);
  // 直接通过videoId推导当前视频源,无需单独维护状态
  const currentVideo = exercises.find(item => item.id === videoId)?.videoSrc;

  function handleNext() {
    setVideoId(prevId => {
      const nextId = prevId + 1;
      // 处理边界,到最后一个视频后回到第一个
      return nextId > exercises.length ? 1 : nextId;
    });
  }

  return (
    <>
      <div className="">
        <div className="mb-4">
          <VideoPlayer src={currentVideo} />
        </div>
        <div className="">          
          <Button onClick={handleNext} size="slim">
            Next
          </Button>
        </div>
      </div>
    </>
  );
}

关键优化点

  • 移除冗余的videoSrc状态,直接通过videoId从exercises数组推导视频源,避免状态不同步。
  • 使用useState的函数式更新,确保获取最新的状态值,解决异步更新导致的旧值问题。
  • 添加边界处理,防止videoId超出数组长度范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:21:07