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
相关产品推荐
相关产品推荐

