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

React组件Props更新异常:GameState组件Props始终滞后一轮

问题解决:子组件状态更新后父组件接收值滞后一轮

问题现象

通过GameInfo组件的下拉框切换难度后,GameState组件显示的difficulty属性值始终比实际选中的难度配置滞后一轮——比如选中「Normal」难度时,GameState仍显示「Easy」的7秒,再次切换到「Hard」时才显示「Normal」的5秒,该问题可通过控制台日志及界面演示复现。

问题根源

React的useState状态更新是异步的。在GameInfo组件的changeDifficultyHandler函数中,调用setDifficulty(levels[event.target.value])后立刻使用当前的difficulty状态传递给父组件,此时difficulty还未完成更新,传递的仍是更新前的旧值,导致父组件的currentDifficulty状态滞后,最终GameState拿到的props也跟着滞后。

解决方案

有两种可行的修复方式:

方案1:直接传递选中的最新难度值

不需要依赖组件内部的difficulty状态,直接将选中的levels[event.target.value]传给父组件:

const changeDifficultyHandler = (event) => {
  const selectedDifficulty = levels[event.target.value];
  setDifficulty(selectedDifficulty);
  props.onChangeDifficulty(selectedDifficulty);
};

方案2:使用useEffect监听状态变化

通过useEffect监听difficulty状态的更新,当状态变化时再通知父组件:

import { useState, useEffect } from 'react';

const GameInfo = (props) => {
  // ... 其他代码不变

  useEffect(() => {
    props.onChangeDifficulty(difficulty);
  }, [difficulty, props.onChangeDifficulty]);

  const changeDifficultyHandler = (event) => {
    setDifficulty(levels[event.target.value]);
  };

  // ... 其他代码不变
};

代码修改示例(方案1)

修改后的GameInfo组件代码:

import { useState } from 'react';

const GameInfo = (props) => {
  const levels = {
    Easy: {
      time: 7,
      wordCount: 15,
    },
    Normal: {
      time: 5,
      wordCount: 25,
    },
    Hard: {
      time: 3,
      wordCount: 30,
    },
  };

  const [difficulty, setDifficulty] = useState(levels.Easy);

  const changeDifficultyHandler = (event) => {
    const selectedLevel = levels[event.target.value];
    setDifficulty(selectedLevel);
    props.onChangeDifficulty(selectedLevel);
  };

  return (
    <div>
      You Are Playing On The{' '}
      <span>
        [
        <select onChange={changeDifficultyHandler}>
          <option value='Easy'>Easy</option>
          <option value='Normal'>Normal</option>
          <option value='Hard'>Hard</option>
        </select>
        ]
      </span>{' '}
      Difficulty & You Have{' '}
      <span className='text-main font-poppins font-bold'>
        [ {difficulty.time} ]
      </span>{' '}
      Seconds To Type The Word.
    </div>
  );
};

export default GameInfo;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:11:30