首页 > 解决方案 > React - 动态更新新输入的总数

问题描述

我有三个数字类型的输入字段(受控输入以接受 [0-100] 范围内的数字)。和一个文本字段来显示总数。

输入字段:

<Input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode1} />
<Input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode2} />
<Input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode3} />

总字段:

<Text fontSize={14} weight={700}>{this.state.total}</Text>

更新代码功能:

updateCode1(value) {
    this.setState({ code1: value },
      () => {
        this.updateTotal();
      });
  }
updateCode2(value) {
     this.setState({ code2: value },
      () => {
        this.updateTotal();
      });
  }
updateCode3(value) {
     this.setState({ code3: value },
      () => {
        this.updateTotal();
      });
  }

更新总数:

updateTotal() {
    this.setState(prevState => ({
      total: (prevState.code1 + prevState.code2 + prevState.code3),
    }),
    () => {
      if (this.state.total !== 100) {
        this.setState({ isTotalInvalid: true });
      } else {
        this.setState({ isTotalInvalid: false });
      }
    });
  }

但它没有计算总数。有任何想法吗?谢谢!

标签: javascriptreactjs

解决方案


value传递给的updateCodeX不是它自己的值,而是event内部的值event.target.value,并添加+以将状态值转换为数字:

class Test extends React.Component {
  state = {
    code1: 40,
    code2: 40,
    code3: 40,
    total : 0
  }
  
  updateCode1 = e => {
    this.setState({
        code1: e.target.value
      },
      () => {
        this.updateTotal();
      });
  }
  updateCode2 = e => {
    this.setState({
        code2: e.target.value
      },
      () => {
        this.updateTotal();
      });
  }
  updateCode3 = e => {
    this.setState({
        code3: e.target.value
      },
      () => {
        this.updateTotal();
      });
  }

  updateTotal = () => {
    this.setState(prevState => ({
        total: (+prevState.code1 + +prevState.code2 + +prevState.code3),
      }),
      () => {
        if (this.state.total !== 100) {
          this.setState({
            isTotalInvalid: true
          });
        } else {
          this.setState({
            isTotalInvalid: false
          });
        }
      });
  }

  render() {
    return (
        <div>
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode1} />
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode2} />
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={this.updateCode3} />
          Total Field:

          <span fontSize={14} weight={700}>{this.state.total}</span>
        </div>);
    }
  }

ReactDOM.render( < Test / > , document.querySelector('#test'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="test"></div>

我建议对您的代码稍作改进,使用一个函数updateCode来更新 state 中的代码:

class Test extends React.Component {
  state = {
    code1: 40,
    code2: 40,
    code3: 40,
    total : 0
  }
  
  updateCode = (e, k) => {
    this.setState({
        [`code${k}`]: e.target.value
      },
      () => {
        this.updateTotal();
      });
  }

  updateTotal = () => {
    this.setState(prevState => ({
        total: (+prevState.code1 + +prevState.code2 + +prevState.code3),
      }),
      () => {
        if (this.state.total !== 100) {
          this.setState({
            isTotalInvalid: true
          });
        } else {
          this.setState({
            isTotalInvalid: false
          });
        }
      });
  }

  render() {
    return (
        <div>
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={e => this.updateCode(e, 1)} />
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={e => this.updateCode(e, 2)} />
          <input type="number" defaultValue="40" min="0" max="100" onKeyPress={this.handleInput} onBlur={e => this.updateCode(e, 3)} />
          Total Field:

          <span fontSize={14} weight={700}>{this.state.total}</span>
        </div>);
    }
  }

ReactDOM.render( < Test / > , document.querySelector('#test'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="test"></div>


推荐阅读