Redux reducer:我在这里改变状态吗?

Redux reducer: am i mutating the state here?

我制作了一个计算器应用程序,其中有一行(我可以看到,如果还有其他问题请告诉我)我认为我正在改变状态但我不应该这样做? (是的,我正在使用 eval() 来做到这一点)。这是错的吗? 这条线

     return eval(state.replace(/x/g, '*').replace(/÷/g, '/'))

减速器:

 import { NUMBER_BUTTON, EQUALS_BUTTON, CLEAR_BUTTON, DECIMAL_BUTTON } from '../actions'

export default function calc(state = '', action) {
  switch (action.type) {
    case NUMBER_BUTTON:
      return state+=action.value
    case DECIMAL_BUTTON:
      if(state.indexOf('.') > -1 ){
        return state
      }
      return state+='.'
    case EQUALS_BUTTON:
      if(state.length > 0){
        return eval(state.replace(/x/g, '*').replace(/÷/g, '/'))
      }
    case CLEAR_BUTTON:
      return ''
    default:
      return state
  }
}

组件代码:供参考

  <View style={styles.container}>
    <View style={styles.result}>
      <Text style={styles.totalText}>{total}</Text>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => number('1')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>1</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight onPress={() => number('2')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>2</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number('3')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>3</Text>
        </View>
      </TouchableHighlight>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => number('4')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>4</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number('5')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>5</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number('6')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>6</Text>
        </View>
      </TouchableHighlight>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => number('7')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>7</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number('8')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>8</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number('9')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>9</Text>
        </View>
      </TouchableHighlight>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => number('0')}>
        <View style={[styles.button, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>0</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => decimal('.')}>
        <View style={[styles.btnMath, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>.</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number(' + ')}>
        <View style={[styles.btnMath, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>+</Text>
        </View>
      </TouchableHighlight>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => number(' - ')}>
        <View style={[styles.btnMath, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>-</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number(' ÷ ')}>
        <View style={[styles.btnMath, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>÷</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => number(' x ')}>
        <View style={[styles.btnMath, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>x</Text>
        </View>
      </TouchableHighlight>
    </View>
    <View style={styles.row}>
      <TouchableHighlight  onPress={() => clear()}>
        <View style={[styles.btnClear, this.calculatedSize()]}>
          <Text style={styles.btnTxt}>C</Text>
        </View>
      </TouchableHighlight>
      <TouchableHighlight  onPress={() => equals()}>
        <View style={[styles.btnEquals, this.calculatedEqualsSize()]}>
          <Text style={styles.btnTxt}>=</Text>
        </View>
      </TouchableHighlight>
    </View>
  </View>

看起来不像。 eval() 调用似乎只是评估表达式的 return 值,它应该是完全独立的

虽然你变异状态,但在这些行中:

case NUMBER_BUTTON:
  return state+=action.value // <------ mutate
case DECIMAL_BUTTON:
  if(state.indexOf('.') > -1 ){
    return state
  }
  return state+='.' // <-------- mutate

+= 运算符是一个禁忌。只需将其更改为 + 运算符,因为您正在 return 新状态,一切都应该没问题。