我正在尝试制作一个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;
答案 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;
答案 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()});
我想这会解决。