In this React Javascript Calculator this.setState({ array: displayed});
is supposed to update the array in state, but it doesn't. Is there a way to force it? Any help would be greatly appreciated.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './style.css';
class JavascriptCalculator extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 0,
array: [],
operators:['+']
}
this.display = this.display.bind(this);
this.clear = this.clear.bind(this);
this.calculate = this.calculate.bind(this);
}
display(text){
// if display is zero, remove the leading zero from the text.
if(this.state.text == 0){
this.state.text = ''
}
let regex = /[*/+-]/;
// if text is not an operator
if (!regex.test(text)){
let displayed = this.state.text
// disallow consecutive decimal points
if (text == '.' && displayed.slice(-1) == '.'){
return;
}
// start by adding text
displayed = this.state.text += text;
// disallow multiple decimal points in a number
// if attempt at more than one decimal point remove last one.
let array = displayed.split('');
let count = 0;
for (let i = 0; i < array.length; i++){
if (array[i] == '.'){
count++;
}
}
// one decimal point is allowed per operator.
// thus to allow the first decimal point,
// this.state.operators must be initialized
// to length of 1.
if(count > this.state.operators.length){
array.pop();
}
displayed = array.join('');
this.setState({ text: displayed});
}
// if text is an operator
if (regex.test(text)){
// add the text to the array
// so that repeated decimal points are prevented
let array = this.state.operators;
array.push(text);
this.setState({ operators: array});
// add the text to the text
let displayed = this.state.text += text;
this.setState({ text: displayed});
}
// if text ends in equals sign, run the calculate function.
if (text == '='){
let displayed = this.state.text.split('');
console.log(displayed);
this.setState({ array: displayed});
//this.state.array = displayed;
this.calculate();
}
}
calculate(){
let regex = /[*/+-]/;
let text = '';
let length = this.state.array.length;
let operators = [];
//console.log(this.state.array);
// capture numbers longer than one digit by adding them to a string
// and adding a comma in place of the operators, so the string
// can be split into an array at the operators.
for (let i = 0; i < length; i++){
// put numbers into a string
if (this.state.array[i].match(/[\d.]/)) {
text+=this.state.array[i];
}
// add commas to string in place of operators
if (this.state.array[i].match(regex)){
text+=',';
// add operators to their own array
operators.push(this.state.array[i]);
}
if (this.state.array[i] == '='){
break;
}
}
//console.log(operators);
// create the numbers array
let numbers = text.split(',');
//console.log(numbers);
// initialize answer with first number
let answer = numbers[0];
let func = undefined;
// Start with second number
for (let i = 1; i < numbers.length; i++){
func = returnFunc(operators.shift());
console.log(func);
answer = func(answer, numbers[i]);
}
this.display(answer);
function returnFunc(val) {
switch (val) {
case '+':
return function sum(a,b) { return Number(a)+Number(b)};
case '-':
return function subtract(a,b) { return Number(a)-Number(b)};
case '*':
return function multiply(a,b) { return Number(a)*Number(b)};
case '/':
return function divide(a,b) { return Number(a)/Number(b)};
default:
throw new Error("Called with unknown operator " + val);
}
}
}
clear(id){
this.setState({ text: id });
this.setState({ array: [] });
this.setState({ operators: [] });
}
render() {
return (
<div id="javascript-calculator">
<h1 id="title">Javascript Calculator</h1>
<div id="display">{this.state.text}</div>
<hr/>
<div>
<button id="clear" onClick={e => this.clear("0")}> clear </button>
<button id="equals" onClick={e => this.display("=")}> = </button>
<button id="zero" onClick={e => this.display("0")}> 0 </button>
<button id="one" onClick={e => this.display("1")}> 1 </button>
<button id="two" onClick={e => this.display("2")}> 2 </button>
<button id="three" onClick={e => this.display("3")}> 3 </button>
<button id="four" onClick={e => this.display("4")}> 4 </button>
<button id="five" onClick={e => this.display("5")}> 5 </button>
<button id="six" onClick={e => this.display("6")}> 6 </button>
<button id="seven" onClick={e => this.display("7")}> 7 </button>
<button id="eight" onClick={e => this.display("8")}> 8 </button>
<button id="nine" onClick={e => this.display("9")}> 9 </button>
<button id="add" onClick={e => this.display("+")}> + </button>
<button id="subtract" onClick={e => this.display("-")}> - </button>
<button id="multiply" onClick={e => this.display("*")}> * </button>
<button id="divide" onClick={e => this.display("/")}> / </button>
<button id="decimal" onClick={e => this.display(".")}> . </button>
</div>
</div>
);
}
}
ReactDOM.render(<JavascriptCalculator />, document.getElementById("app"));
index.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Javascript Calculator</title>
<style>
</style>
</head>
<body>
<main>
<div id="app"></app>
</main>
</body>
</html>
setState is async. It won't work how you're using it. In your case, you should just pass the displayed
array to the calculate function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.