【发布时间】:2018-04-24 19:23:12
【问题描述】:
我目前正在努力获得我的全栈,并决定扩展我对 JavaScript 的了解。这个决定最终把我带到了 React,但我 - 如前所述 - 这个库中的菜鸟。但这仅意味着我必须更多地使用这项技术才能在所述知识方面取得进步。
乍一看,我正在处理的实际问题似乎很简单;显然我的反应应用程序没有正确更新 this.state 。我知道 React 中的 setState 方法是异步的,所以当触发 setState() 的内置第二个回调时,我会触发其他自定义方法。这种技术显然不是最好的,因为它根本没有按计划工作。
我的应用是关于一个带有基本数学运算符的简单计算器。我想实现一个功能,在“输入”下实时跟踪给定表达式的潜在结果,但是我的方法不起作用,尽管我认为它离真正的解决方案并不太远。正确的函数在正确的时间被触发,但是 this.state.result 和 this.state.resultExpression 显然都没有,因为它们没有出现在它们的渲染框中。我的 updateDigit() 函数按计划工作,但是在点击“等于”按钮后显示结果时,实际上什么都没有显示 - 甚至整个输入的输入都消失了。
这是我的代码:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './calc.css';
const showHistory = false;
const decimalPlace = 3;
const operatorSet = ["+", "-", '*', '/', '%'];
class Calculator extends Component {
constructor(props) {
super(props);
this.recentResult == false;
this.state = {
output: '0',
preview: '',
history: [],
result: '',
resultExpression: ''
};
this.updateDigit = this.updateDigit.bind(this);
this.updatePreview = this.updatePreview.bind(this);
this.clearOutput = this.clearOutput.bind(this);
this.getResult = this.getResult.bind(this);
this.showResult = this.showResult.bind(this);
}
render() {
return (
<div className="calculator">
<div className="comp5">
<div className="output">{this.state.output}</div>
<div className="preview">{this.state.getResult}</div>
</div>
<div className="comp4">
<div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>(</a></div>
<div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>)</a></div>
<div className="topbtn"><a href="#" draggable="false" onClick={this.updateDigit}>%</a></div>
<div className="button_div button_control">
<a href="#" draggable="false" onClick={this.updateDigit}>/</a>
</div>
</div>
<div className="comp3">
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>7</a></div>
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>8</a></div>
<div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>9</a></div>
<div className="button_min button_control">
<a href="#" draggable="false" onClick={this.updateDigit}>*</a>
</div>
</div>
<div className="comp2">
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>4</a></div>
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>5</a></div>
<div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>6</a></div>
<div className="button_plus button_control">
<a href="#" draggable="false" onClick={this.updateDigit}>-</a>
</div>
</div>
<div className="comp1">
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>1</a></div>
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>2</a></div>
<div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>3</a></div>
<div className="button_plus button_control">
<a href="#" draggable="false" onClick={this.updateDigit}>+</a>
</div>
</div>
<div className="comp0">
<div className="numpad clear"><a href="#" draggable="false" onClick={this.clearOutput}>C</a></div>
<div className="numpad"><a href="#" draggable="false" onClick={this.updateDigit}>0</a></div>
<div className="numpad npl"><a href="#" draggable="false" onClick={this.updateDigit}>.</a></div>
<div className="button_res button_control">
<a href="#" draggable="false" onClick={this.showResult}>=</a>
</div>
</div>
<History expressions={this.state.history} />
</div>
);
}
updateDigit(event) {
event.preventDefault;
if (this.recentResult == true || this.state.output == "0") {
this.recentResult = false;
this.setState({ output: '' });
}
const newDigit = {
digit: event.target.innerHTML,
id: Date.now()
};
this.setState(prevState => ({
output: prevState.output.concat(newDigit.digit)
}), this.updatePreview());
}
updatePreview(event) {
if (this.state.output == "0") {
this.setState({ preview: '' });
}
let checkPreviewable = (output) => {
var charactersAfterOperator = false;
for (var i = 0; i < operatorSet.length; i++) {
var currentOperator = operatorSet[i];
let operatorLocation = output.indexOf(currentOperator)
if (operatorLocation < output.length && operatorLocation > 0) {
return true;
} else {
return false;
}
}
};
let previewable = checkPreviewable(this.state.output);
if (previewable === true) {
let resultExpression = this.state.resultExpression;
this.setState({ preview: this.state.result });
} else {
this.setState({ preview: '' });
}
}
clearOutput(event) {
event.preventDefault();
this.setState({ output: '0' });
}
getResult(event) {
var result = eval(this.state.output).toFixed(decimalPlace);
var resultExpression = this.state.output + "=" + result;
this.setState({
result: result,
resultExpression: resultExpression
}, this.updatePreview());
}
showResult(event) {
this.getResult();
let result = this.state.result;
let resultExpression = this.state.resultExpression;
this.setState({ output: result });
this.setState(prevState => ({
history: prevState.history.concat(resultExpression)
}));
this.recentResult = true;
}
}
export default Calculator;
class History extends React.Component {
render() {
if (showHistory === false) return false;
return (
<ul>
{this.props.expressions.map(expression => (
<li>{expression}</li>
))}
</ul>
)
}
}
您是否知道为什么会发生这种情况,您是否真的遇到过类似的情况,或者您甚至可以提供替代/解决方案吗?
提前感谢您的各种帮助,J0nny
【问题讨论】:
标签: javascript reactjs frontend web-frontend