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

ReactJS中setState内如何将对象属性赋值给同一对象的其他属性

问题原因

你在setState的函数式更新回调中拿到的currentState是本次状态更新触发前的旧状态,同一次setState返回对象中定义的新属性不会同步更新到currentState里,所以你直接用currentState.value1拿到的永远是上一轮的旧值,无法实现用本次新生成的三个值计算后续属性的需求。另外你代码中对setState的手动绑定属于多余操作,可以直接删除。

解决方案

直接在setState的更新回调内部先预计算本次要更新的所有衍生值,再统一组装到返回的状态对象中即可。同时可以把生成新题的公共逻辑抽成单独方法,避免两个按钮回调里的重复代码。

修正后完整代码
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(){
    super();
    const value1 = Math.floor(Math.random() * 100);
    const value2 = Math.floor(Math.random() * 100);
    const value3 = Math.floor(Math.random() * 100);
    const proposedAnswer = Math.floor(Math.random() * 3) + value1 + value2 + value3;
    const numQuestions = 0;
    const numCorrect = 0;
    const check = proposedAnswer === value1 + value2 + value3;
    this.state = {
      value1: value1,
      value2: value2,
      value3: value3,
      proposedAnswer: proposedAnswer,
      numQuestions: numQuestions,
      numCorrect: numCorrect,
      check: check
    };
  }

  // 抽离生成新题的公共逻辑
  generateNewProblem = () => {
    const value1 = Math.floor(Math.random() * 100);
    const value2 = Math.floor(Math.random() * 100);
    const value3 = Math.floor(Math.random() * 100);
    const proposedAnswer = Math.floor(Math.random() * 3) + value1 + value2 + value3;
    const check = proposedAnswer === value1 + value2 + value3;
    return { value1, value2, value3, proposedAnswer, check };
  }
  
  answerIsTrue = () => {
    this.setState((currentState) => {
      // 先预计算好本次要更新的题目相关值
      const newProblem = this.generateNewProblem();
      return {
        numCorrect: currentState.check ? currentState.numCorrect + 1 : currentState.numCorrect,
        numQuestions: currentState.numQuestions + 1,
        ...newProblem
      }
    })
  }
  
  answerIsFalse = () => {
    this.setState((currentState) => {
      const newProblem = this.generateNewProblem();
      return {
        numCorrect: !currentState.check ? currentState.numCorrect + 1 : currentState.numCorrect,
        numQuestions: currentState.numQuestions + 1,
        ...newProblem
      }
    })
  }
  
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">ReactND - Coding Practice</h1>
        </header>
        <div className="game">
          <h2>Mental Math</h2>
          <div className="equation">
            <p className="text">{`${this.state.value1} + ${this.state.value2} + ${this.state.value3} = ${this.state.proposedAnswer}`}</p>
          </div>
          <button onClick={() => this.answerIsTrue()}>
            True
          </button>
          <button onClick={() => this.answerIsFalse()}>
            False
          </button>
          <p className="text">
            Your Score: {this.state.numCorrect}/{this.state.numQuestions}
          </p>
        </div>
      </div>
    );
  }
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:15:02