降低功能复杂度

时间:2020-02-17 15:02:04

标签: javascript reactjs if-statement javascript-objects

我在React中编写一个简单的计算器。我试图根据单击的按钮来更新组件的状态(如您所愿)。组件的状态如下:

this.state = {
  total: null,
  next: null,
  operation: null,
}

目前,我有一条很长的if / else语句,该语句检查一堆方案以确定适当的值。我想知道如何重写它以减少功能的复杂性:

handleClick(buttonName) {
    let { total, next } = this.state;
    const { operation } = this.state;
    let obj;
    const nums = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    const syms = ['+', '-', 'X', '/', '%'];
    const equal = '=';
    const reset = 'AC';
    const decimalPoint = '.';

    if (total === null && nums.indexOf(buttonName) >= 0) {
      this.setState({
        total: buttonName,
      });
    } else if (total !== null
      && buttonName === decimalPoint
      && (total.indexOf(decimalPoint) === -1)) {
      this.setState({
        total: total += buttonName,
      });
    } else if (total !== null
      && next !== null
      && buttonName === decimalPoint
      && (next.indexOf(decimalPoint) === -1)) {
      this.setState({
        next: next += buttonName,
      });
    } else if (total !== null
      && operation === null
      && syms.indexOf(buttonName) >= 0) {
      this.setState({
        operation: buttonName,
      });
    } else if (total !== null
      && operation === null
      && nums.indexOf(buttonName) >= 0) {
      this.setState({
        total: total += buttonName,
      });
    } else if (total !== null
      && operation !== null
      && next === null
      && nums.indexOf(buttonName) >= 0) {
      this.setState({
        next: buttonName,
      });
    } else if (total !== null
      && operation !== null
      && next !== null
      && nums.indexOf(buttonName) >= 0) {
      this.setState({
        next: next += buttonName,
      });
    } else if (total !== null
      && operation !== null
      && next !== null
      && ((buttonName === equal) || (buttonName === reset))) {
      obj = method.calculate(this.state, operation);
      this.setState({
        total: obj.total,
        next: obj.next,
        operation: buttonName,
      });
    }
  }

PS。 “ method.calculate”函数在另一个模块中说明。

2 个答案:

答案 0 :(得分:0)

简而言之:

尝试将您的条件值存储在变量中(请尝试给它们取更好的名称)

   const check1 = nums.indexOf(buttonName) >= 0
   const check2 = buttonName === decimalPoint
   const check3 = next.indexOf(decimalPoint) === -1)

然后,尝试使用变量而不是表达式将您的语句重构为嵌套的。例如:

    if (total) {
     if (check2 && check3) {
        if (next) {
           this.setState({ next: next += buttonName });
        }
        else {
           this.setState({total: total += buttonName });
        }
     }
     else {
     }
    } 

这当然只是一个建议。就您而言,它将:

  • 停止一遍又一遍地重新计算表达式
  • 使代码更具可读性和可维护性
  • 允许您与其他开发人员合作

是的。Stack Exchange Code review是一件事:)

答案 1 :(得分:0)

您可以reify单击处理程序条件,然后让实用程序功能选择并调用相关处理程序。

我不确定这是否可以解决您的问题,因为我不确定对state的引用是否恒定以及setState是否依赖于目标,但这只是一个示例。

编辑:我已经研究了React的工作方式,下面的精确代码可能不会工作,但一般的方法是合理的。

const createHandler = 
    ({ state, setState }) => 
        (buttonName) => handlers.some(({condition, action}) => 
            condition({ buttonName, state: this.state}) && 
            action({buttonName, state, setState}) && 
            true)

const handlers = [ 
    { 
        condition: ({ state: { total }}) => {
            const nums = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
            return (total === null && nums.indexOf(buttonName) >= 0)
        },
        action: ({ buttonName, setState }) => setState({ total: buttonName })
    },
    // ...
];

class MyComponent {
    constructor() {
        this.handle = createHandler({ state: this.state, setState: this.setState })
    }

    handleClick(buttonName) {
        this.handle(buttonName)
    }
}