首先,我为代码I道歉,如果它相当混乱,但我现在不能修复它.我的计算器第一次工作时,当我输入数值,按下等号后,事情开始变得混乱.我的Redux历史记录属性必须保存最后一次计算的结果,但它会拆分结果,例如:174->;1,7,4.代码是用codesen编写的,所以我们在幕后连接的库
const UPDATE = 'UPDATE';
const RESTART = 'RESTART';
const SOLVE = 'SOLVE';
const CONT = 'CONT';
const regexp = /[+*/]/;
const regex = /[\(\)]/g;
const update = (inputValue) => {
return {
type: 'UPDATE',
input: inputValue
}
}
const restart = () => {
return {
type: 'RESTART'
}
}
const cont = () => {
return {
type: 'CONT'
}
}
const calc = () => {
return{
type: 'SOLVE'
}
}
const initialState = {
history: [],
output: ''
}
const reducer = (state = initialState, action) => {
switch(action.type){
case 'UPDATE':
return {
...state,
history: [...state.history, action.input],
}
break;
case 'RESTART':
return state = initialState;
break;
case 'SOLVE':
console.log(state.history)
const app = state.history.map((ele) => {
return ele.replace(regex, "").toString()
});
console.log('--------------------------------------')
const divide = '/';
const multiply = '*';
while(app.includes('/') || app.includes('*')){
let priores;
if(app.includes('/')){
const divideIndex = app.findIndex((element) => element === '/');
priores = parseFloat(app[divideIndex - 1]) / parseFloat(app[divideIndex + 1]);
app.splice(divideIndex - 1, 3, priores.toString());
} else if (app.includes('*')) {
const multiplyIndex = app.findIndex((element) => element === '*');
priores = parseFloat(app[multiplyIndex - 1]) * parseFloat(app[multiplyIndex + 1]);
app.splice(multiplyIndex - 1, 3, priores.toString());
}
}
if(app.length == 1){
return {
...state, output: app, history: app
}
}
let result = parseFloat(app.slice(0, 1));
for(let i = 0; i < app.length; i++){
if (app[i] == '+') {
if(app[i + 1].includes('.')){
result *= 1000;
result += parseFloat(app[i + 1]) * 1000;
result /= 1000;
}else{
result += parseFloat(app[i + 1]);
}
} else if (app[i] == '-') {
if(app[i + 1].includes('.')){
result *= 1000;
result -= parseFloat(app[i + 1]) * 1000;
result /= 1000;
}else{
result -= parseFloat(app[i + 1]);
}
}
}
return {
...state, output: result.toString(), history: result.toString()
}
break;
case 'CONT':
return {...state, output: ''}
break;
default:
return state;
break;
}
}
const store = Redux.createStore(reducer);
//React
class Calculator extends React.Component{
constructor(props){
super(props);
this.state = {
input: '0',
negativeCount: 0
}
this.handleClick = this.handleClick.bind(this);
this.handleAc = this.handleAc.bind(this);
this.handleOp = this.handleOp.bind(this);
this.handleEquals = this.handleEquals.bind(this);
}
handleClick = (event) => {
if(this.props.resul == ''){
console.log(this.props.history)
console.log(this.state.input)
{this.state.input == "0" && this.setState({input: ''})}
if(this.state.input == '+' || this.state.input == '/' || this.state.input == '*'){
this.props.upd(this.state.input)
this.setState({
input: ''
})
}
if(this.state.input == '-'){
this.props.upd(this.state.input);
this.setState({
input: '',
negativeCount: 0
})
}
if(this.state.input.includes('(-') && this.state.input != '(-0)'){
if(this.state.input.includes(')')){
this.setState({
input: this.state.input.replace(')', '')
})
this.setState((state)=> ({
input: state.input.concat(val).concat(')'),
negativeCount: 0
}));
}else{
const val = event.target.innerText;
this.setState((state)=> ({
input: state.input.concat(val).concat(')'),
negativeCount: 0
}));
}
}else if(this.state.input != '(-0)'){
const val = event.target.innerText;
this.setState((state)=> ({
input: state.input.concat(val),
negativeCount: 0
}));
}
const val = event.target.innerText;
if(this.state.input == '(-0)'){
this.setState({input: '(-'.concat(val).concat(')')})
}
}
}
handleOp = (event) => {
if(this.props.resul != ''){
this.props.cont();
const op = event.target.innerText;
this.setState({
input: op
})
console.log('this s')
console.log(this.props.history)
}else{
if(this.state.input != '(-0)'){
let signOpCheck = regexp.test(this.state.input);
let signCheck = this.state.input.split('');
const op = event.target.innerText;
if(op == '-' && this.state.negativeCount < 1 && signCheck[signCheck.length - 1] != '.' && this.state.input != "(-"){
this.setState({
input: op,
negativeCount: this.state.negativeCount + 1
})
}else if(op == '-' && this.state.negativeCount > 0 && signCheck[signCheck.length - 1] != '.' && this.state.input != "(-"){
this.props.upd(this.state.input);
this.setState({
input: '',
negativeCount: 0
})
this.setState({
input: '(-'
})
}
if(signOpCheck == false && signCheck[signCheck.length - 1] != '.' && signCheck[signCheck.length - 1] != '-' && signCheck != '(-' && this.state.input != ''){
this.props.upd(this.state.input);
console.log(this.props.history)
this.setState((state) => ({
input: op,
negativeCount: state.negativeCount + 1
}))
}
}}
}
handleAc = () => {
this.setState({
input: '0',
negativeCount: 0
})
this.props.res();
}
handleDecimal = () => {
if(this.props.result == ''){
let signOpCheck = regexp.test(this.state.input);
{this.state.input == '0' && this.setState({last: '0'})}
let dotCheck = this.state.input.includes('.');
if(dotCheck == false && signOpCheck == false && this.state.input != "(-"){
if(this.state.input[this.state.input.length - 1] == ')'){
this.setState({
input: this.state.input.replace(')', '.')
})
}else if(dotCheck == false && signOpCheck == false && this.state.input != '-'){
this.setState((state) => ({
input: state.input.concat('.')
}))}
}}}
handleEquals = () => {
{this.state.input != '' && this.props.upd(this.state.input)}
this.props.calculate();
this.setState({
input: this.props.resul
});
}
render(){
return(
<div id = 'calc'>
<div id = 'screen'>
<div id = 'history'>{this.props.history}{this.state.input}</div>
<div id = 'display'><div id = "output">{this.state.input}{this.props.resul}</div></div>
</div>
<div id = "keys">
<button id = "clear" className="bg-danger" onClick = {this.handleAc}>AC</button>
<button id = "divide" className="bg-secondary" onClick = {this.handleOp}>/</button>
<button id = "multiply" className="bg-secondary" onClick = {this.handleOp}>*</button>
<button id = "seven" onClick = {this.handleClick}>7</button>
<button id = "eight" onClick = {this.handleClick}>8</button>
<button id = "nine" onClick = {this.handleClick}>9</button>
<button id = "subtract" class="bg-secondary" onClick = {this.handleOp}>-</button>
<button id = "four" onClick = {this.handleClick}>4</button>
<button id = "five" onClick = {this.handleClick}>5</button>
<button id = "six" onClick = {this.handleClick}>6</button>
<button id = "add" class="bg-secondary" onClick = {this.handleOp}>+</button>
<button id = "one" onClick = {this.handleClick}>1</button>
<button id = "two" onClick = {this.handleClick}>2</button>
<button id = "three" onClick = {this.handleClick}>3</button>
<button id = "equals" class="bg-primary" onClick={this.handleEquals}>=</button>
<button id = "zero" onClick = {this.handleClick}>0</button>
<button id = "decimal" onClick = {this.handleDecimal}>.</button>
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
history: state.history,
resul: state.output
}
}
const mapDispatchToProps = (dispatch) => {
return {
upd: (inputValue) =>
dispatch(update(inputValue)),
res: () => dispatch(restart()),
calculate: () => dispatch(calc()),
cont: () =>
dispatch(cont())
}
}
const Provider = ReactRedux.Provider;
const connect = ReactRedux.connect;
const Connected = connect(mapStateToProps, mapDispatchToProps)(Calculator);
ReactDOM.render(
<Provider store = {store}>
<Connected />
</Provider>,
document.getElementById('app'));
Note that if I multiply or divide without using + or - the calculator works as intended. however using + or - operations make it fill the history array with the result in the incorrect format.Some notes for your convenience: redux operates with the history array which held all the signs and numbers typed by a user. handleClick function is invoked when pressing any number. handleOp stand for handleOperator -+/*. the code has messy parts concerning the conditions for the handles. they were used to make calcs with negative signs possible.
after pressing the equal sign history holds correct format of the result but after pressing any operation sign and a number right after makes in held the splitter result.I know that the code is overcomplicated. At least I want to find out the reason for this bug, so I appreciate every effort to help