限制输入数量

时间:2018-10-21 15:25:44

标签: reactjs

我正在尝试制作一个React计算器。它大部分都已完成,但是我有一个我不知道如何纠正的问题:我不想让用户输入以多个“ 0”开头的表达式,而诸如“ 01”的表达式应替换为“ 1”。我曾考虑过使用字符串方法来限制它,但这并不是很容易。 编辑:我知道为什么我的解决方案不起作用(输入永远不会有多个零),但我不知道其他任何解决方法。

class Calculator extends Component {
constructor(props) {
    super(props);
    this.state = { value: "" };
    this.handleClick = this.handleClick.bind(this);
}
handleClick(evt) {
    const id = evt.target.id;
    const result = evt.target.value;
    if (id === "clear") {
    this.setState({ value: 0 });
    } else if (id === "equals") {
    this.setState({ value: math.eval(this.state.value) });
    } else {
    result.toString().includes("00");
    this.setState({ value: this.state.value + result.replace("00", "0") });
    console.log(this.state.value);
    }
}

render() {
    return (
    <div id="container">
        <Display value={this.state.value} />
        <Button onClick={this.handleClick} id="zero" value={"0"} />
        <Button onClick={this.handleClick} id="one" value={"1"} />
        <Button onClick={this.handleClick} id="two" value={"2"} />
        <Button onClick={this.handleClick} id="three" value={"3"} />
        <Button onClick={this.handleClick} id="four" value={"4"} />
        <Button onClick={this.handleClick} id="five" value={"5"} />
        <Button onClick={this.handleClick} id="six" value={"6"} />
        <Button onClick={this.handleClick} id="seven" value={"7"} />
        <Button onClick={this.handleClick} id="eight" value={"8"} />
        <Button onClick={this.handleClick} id="nine" value={"9"} />
        <Button onClick={this.handleClick} id="decimal" value={"."} />
        <Button onClick={this.handleClick} id="equals" value={"="} />
        <Button onClick={this.handleClick} id="clear" value={"clear"} />
        <Button onClick={this.handleClick} id="add" value={"+"} />
        <Button onClick={this.handleClick} id="subtract" value={"-"} />
        <Button onClick={this.handleClick} id="multiply" value={"*"} />
        <Button onClick={this.handleClick} id="divide" value={"/"} />
    </div>
    );
}
}
export default Calculator;

3 个答案:

答案 0 :(得分:2)

result将始终只包含一个数字。您想要的是将新数字添加到现有值,然后替换:

this.setState(prevState => ({ value: (prevState.value + result).replace("00", "0") }));

但是,此代码有错误,因为您将永远无法输入100,因此它将始终更改为10

所以正确的逻辑是添加起始锚点:

this.setState(prevState => ({ value: (prevState.value + result).replace(/^00/, "0") }));

更新:

要实现您的实际目标,可以使用类似以下内容的代码(不是最干净的代码,但应该可以理解我的意思):

import React from "react";

const availableButtons = [
  "0",
  "1",
  "2",
  "3",
  "4",
  "5",
  "6",
  "7",
  "8",
  "9",
  ".",
  "=",
  "clear"
];
const operators = ["+", "-", "*", "/"];

class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.state = { values: [], value: "", currentNumber: "" };
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(value) {
    if (value === "clear") {
      this.setState({ values: [], value: "", currentNumber: "" });
    } else if (value === "=") {
      this.setState({
        value: eval(this.state.value),
        values: [],
        currentNumber: ""
      });
    } else {
      if (operators.indexOf(value) !== -1) {
        this.setState(prevState => ({
          values: [...prevState.values, prevState.currentNumber, value],
          currentNumber: "",
          value: prevState.value + value
        }));
      } else {
        this.setState(prevState => {
          const currentNumber = this.formattedNumber(
            prevState.currentNumber,
            value
          );
          const newValue = prevState.values.join("") + currentNumber;
          return {
            currentNumber,
            value: newValue
          };
        });
      }
    }
  }

  formattedNumber(previousNumber, newSymbol) {
    if (!previousNumber && previousNumber !== 0) return newSymbol;
    if (
      previousNumber.length === 1 &&
      previousNumber === "0" &&
      newSymbol !== "."
    ) {
      return newSymbol;
    } else {
      return previousNumber + newSymbol;
    }
  }

  render() {
    return (
      <div id="container">
        {this.state.value}
        <br />
        {availableButtons.concat(operators).map(x => (
          <button onClick={() => this.handleClick(x)} key={x}>
            {x}
          </button>
        ))}
      </div>
    );
  }
}
export default Calculator;

Working sample

答案 1 :(得分:2)

一些指针...

  • 如果您希望value是一个字符串,请确保不要在任何地方将其更改为数字。当id ==='clear'
  • 时,您正在执行此操作
  • 如果您只想在"00"的开头测试value,请使用startsWith,而不要使用includes
  • 如果使用setState,并且新状态取决于先前的状态,则必须首先访问该状态的先前值。 rationale for this在文档中。

@ daniel-hilgarth提供了在这种情况下使用setState的正确方法。

删除前导零:

this.setState(prevState => ({
  value: `${prevState.value}${result}`.replace(/^0+\B/, "")
}));

有各种各样的方法可以做到这一点。上面的正则表达式将标识前导零。对于只有"0"的情况,它根本不匹配,因为"0"后跟字符串的末尾(或边界)与正则表达式不匹配,后者是"0"通过“不是单词边界”。

答案 2 :(得分:0)

您可以更改此行

this.setState({ value: this.state.value + result.replace("00", "0") });

对此

let num = this.state.value + Number(result);
this.setState({ value: Number(num).toString()});

我想这会解决。