Снижение сложности функций - PullRequest
0 голосов
/ 17 февраля 2020

Я пишу простой калькулятор в React. Я пытаюсь обновить состояние компонента в зависимости от того, какая кнопка нажата (как и следовало ожидать). Состояние компонента выглядит следующим образом:

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

В настоящее время у меня есть одна длинная инструкция if / else, которая проверяет кучу сценариев ios, чтобы определить, какими должны быть соответствующие значения. Мне интересно, как я мог бы переписать это, чтобы уменьшить сложность функции:

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 голосов
/ 17 февраля 2020

Вы можете изменить условия обработчика щелчков, а затем выбрать служебную функцию и вызвать соответствующий обработчик.

Я не знаю, будет ли это работать в вашем случае, потому что я Я не уверен, является ли ссылка на 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)
    }
}
0 голосов
/ 17 февраля 2020

Короче говоря:

Попробуйте сохранить значения ваших условий в переменных (пожалуйста, попробуйте дать им более подходящие имена)

   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 {
     }
    } 

Это, конечно, просто предложение. В вашем случае:

  • Прекратит повторное вычисление выражений снова и снова
  • Сделает код более читабельным и понятным
  • Позволит вам сотрудничать с другими разработчиками

И да .. Обзор стека обмена кода это вещь:)

...