首先,我为代码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

推荐答案

我认为问题出在"SOLVE"减速器的情况下,最后一个字符串值被保存为state.history.

case 'SOLVE':
  return {
    ...state,
    output: result.toString(),
    history: result.toString()
  }

"UPDATE"的情况下,当添加输入值时,state.history被扩展到新的数组中.

case 'UPDATE':
  return {
    ...state,
    history: [...state.history, action.input],
  }

传播字符串值将创建一个字符array.

const history = parseFloat("174").toString();
console.log([...history]);

我怀疑您的意思是要创建一个新的history数组值.

case 'SOLVE':
  return {
    ...state,
    output: result.toString(),
    history: [result.toString()]
  }

const history = [parseFloat("174").toString()];
console.log([...history]);

Javascript相关问答推荐

更新Reduxstore 中的状态变量,导致整个应用程序出现不必要的重新渲染

如何在加载的元数据上使用juserc和await中获得同步负载?

如何在不分配整个数组的情况下修改包含数组的行为主体?

useNavigation更改URL,但不呈现或显示组件

如何在ASP.NET JavaScript中使用Google Charts API仅对绘制为负方向的条形图移动堆叠条形图标签位置

编辑文本无响应.onClick(扩展脚本)

对网格项目进行垂直排序不起作用

使用js构造一个html<;ath&>元素并不能使其正确呈现

JavaScript不重定向配置的PATH

将异步回调转换为异步生成器模式

在画布中调整边上反弹框的大小失败

匹配一个或多个可选重复的特定模式

使用RxJS from Event和@ViewChild vs KeyUp事件和RxJS主题更改输入字段值

将相关数据组合到两个不同的数组中

在单击按钮时生成多个表单时的处理状态

TypeORM QueryBuilder限制联接到一条记录

Promise.race()返回已解析的promise ,而不是第一个被拒绝的promise

输入数据覆盖JSON文件

在对象的嵌套数组中添加两个属性

在点击链接后重定向至url之前暂停