【问题标题】:ReactJS: doing calculations to setState, and updatingReactJS:对 setState 进行计算并更新
【发布时间】:2019-03-06 10:58:07
【问题描述】:

我想要两个输入数字字段 value1value2 并添加这两个字段的值。然后sum 将保存在this.state.sum 中。我也不想使用“提交”按钮。一些代码:

import React, { Component } from 'react';
import addNumbers from "./components/addNumbers"

class App extends Component {
  constructor() {
    super()
    this.state = {
      value1: 10,
      value2: 3,
      sum: 13
    }
    this.handleChange = this.handleChange.bind(this)
  }

  handleChange(event) {
    //first setState call works fine
    this.setState({[event.target.name]: event.target.value})
    //call addNumbers function
    const sum = addNumbers(this.state.value1, this.statevalue2)
   //this second setState() call will lag by one step
    this.setState({sum: sum})
    console.log(newBarData)
  }

  render() {
    return (
      <div>
        <form>
        <input name="value1" type="number" placeholder="10" onBlur={this.handleChange} />
        <input name="value2" type="number" placeholder="3" onBlur={this.handleChange} />
        </form>
      </div>
    );
  }
}

export default App;

发生的情况是:直到我在页面上进行第二次 更改,第二次setState() 调用才会生效。这是一个相当大的common issue,但我不确定如何解决它。我希望它能够在用户更新表单后立即触发。在实际用例中,将根据用户输入值进行一些计算,然后在图表(plotly.js)上进行可视化,并且我希望能够在每次输入字段更改后“实时”更新图表。

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以使用柯里化在一段代码中创建不同的处理程序(请参阅:makeHandleChange)。然后您可以使用componentDidUpdate 检查您的输入值是否更改以更新您的总和状态值。

    import React, { Component } from 'react';
    import addNumbers from "./components/addNumbers"
    
    class App extends Component {
      state = {
        value1: 10,
        value2: 3,
        sum: 13
      }
    
      componentDidUpdate(lastProps, lastState) {
        const valueChanged = this.state.value1 !== lastState.value1 || this.state.value2 != lastState.value2
        if (valueChanged) {
          const sum = addNumbers(this.state.value1, this.state.value2)
          this.setState({ sum }) 
        }
      }
    
      makeHandleChange = id => ({ target: { value } }) => {
        this.setState({
          [`value${id}`]: value
        })
      }
    
      render() {
        return (
          <div>
            <form>
              <input name="value1" type="number" placeholder="10" onBlur={this.makeHandleChange(1)} />
              <input name="value2" type="number" placeholder="3" onBlur={this.makeHandleChange(2)} />
              <div>the sum is: {this.state.sum}</div>
            </form>
          </div>
        );
      }
    }
    
    export default App;
    

    【讨论】:

    • 这个答案有点工作,但会触发错误:“超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 内重复调用 setState 时,可能会发生这种情况。React 限制嵌套更新的数量以防止无限循环” .我怀疑这是由于componentDidUpdate() 中的if(true) {...} 声明,但我不知道这会如何触发超过两次。
    • 我已经测试了我的代码,我无法重现您的问题:jsfiddle.net/o7zgd8fs/2
    • 它对我来说仍然偶尔发生(可能是因为真正的用例有 4 个输入?)。另外,我使用 ``` handleChange(event) { this.setState({[event.target.name]: parseFloat(event.target.value)}) } ``` 而不是你的makeHandleChange;这可能是个问题吗?
    猜你喜欢
    • 2015-12-17
    • 2017-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 2021-02-24
    • 1970-01-01
    • 2020-02-11
    相关资源
    最近更新 更多