Счетчик инкремента и декремента с вводом с использованием redux

#javascript #reactjs #react-native #redux

#javascript #reactjs #react-native #redux

Вопрос:

Я хочу увеличивать и уменьшать counter.counter1 и counter.counter2.innerCount на входное значение. Вот ошибка, которую я обнаружил сейчас

введите описание изображения здесь

Я слаб в уничтожении объекта и т. Д. И Теперь учусь этому.
Может дать мне какой-нибудь совет или код? Особенно для увеличения и уменьшения для innerCount. Большое спасибо.

actionCreators.js

 import * as actionTypes from "../actionTypes";

export const incrementCounter1 = () => {
  return {
    type: ActionTypes.INCREMENT_COUNTER_1,
  };
};

export const decrementCounter1 = () => {
  return {
    type: ActionTypes.DECREMENT_COUNTER_1,
  };
};

export const incrementByAmount = (amount) => {
  return {
    type: ActionTypes.INCREMENT_BY_AMOUNT,
    amount:amount,
  };
};
 

reducer.js

 import * as actionTypes from "../actionTypes";

const INITIAL_STATE = {
  counter: {
    counter1: 0,
    counter2: {
      innerCount: 0,
    },
  },
};

export const Auth = (state = INITIAL_STATE, action) => {
  const { type, payload } = action;
  let a;
  switch (type) {
    case ActionTypes.INCREMENT_COUNTER_1:
      a = {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1  =1,
        },
      };
      return a;
    case ActionTypes.DECREMENT_COUNTER_1:
      a = {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1 -=1,
        },
      };
      return a;
    case ActionTypes.INCREMENT_BY_AMOUNT:
      a = {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1  =payload,
        },
      };
      return a;
    default:
      return state;
  }
};

export default Auth;
 

mainPage.js

 import React, { useState } from "react";
import { View, Text, StyleSheet, Button, TextInput } from "react-native";
import {
  incrementCounter1,
  decrementCounter1,
  incrementByAmount,
} from "./states/redux/ActionCreators/auth";
import { connect } from "react-redux";


const Counter = ({
  counterRedux,
  incrementCounter1,
  decrementCounter1,
  incrementByAmount,
}) => {
  const [amount, setAmount] = useState('');

  return (
    <View>
      <Text style={styles.text}>Input text for changing</Text>

      <Button title="INCREMENT" onPress={() => incrementCounter1()} />
      <Button title="DECREMENT" onPress={() => decrementCounter1()} />

      <View>
        <Text style={styles.Atext}>Enter amount to increase:</Text>
        <TextInput style={styles.input} value={amount} onChangeText={(a) => setAmount(a)} />
        <Text style={styles.Atext}>Amount: {amount}</Text>
        <Button title='Add Amount' onPress={(amount)=>incrementByAmount(amount)}></Button>
      </View>

      <View>
        <Text style={styles.Atext}>First Counter: {counterRedux.counter1}</Text>
      </View>
    </View>
  );
};

const mapStateToProps = (state) => {
  return {
    counterRedux: state.counter,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    incrementCounter1: () => dispatch(incrementCounter1()),
    decrementCounter1: () => dispatch(decrementCounter1()),
    incrementByAmount: (amount) => dispatch(incrementByAmount(amount)),
  };
};


const styles = StyleSheet.create({
  text: {
    fontSize: 25,
  },
  Atext: {
    fontSize: 20,
  },
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  input: {
    borderWidth: 1,
    borderColor: "#777",
    padding: 8,
    margin: 10,
    width: 200,
  },
  button: {
    backgroundColor: "#fff",
    fontSize: 15,
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(Counter);
 

actionTypes.js

 export const INCREMENT_BY_AMOUNT = 'INCREMENT_BY_AMOUNT';
export const INCREMENT_COUNTER_1 = 'INCREMENT_COUNTER_1';
export const DECREMENT_COUNTER_1 = 'DECREMENT_COUNTER_1';
 

Ответ №1:

Ваша первая проблема здесь: <Button title='Add Amount' onPress={(amount)=>incrementByAmount(amount)}></Button> .
То, что вы делаете, это передача переданному incrementByAmount аргументу onPress , который является вовсе amount не тем, что вы ожидаете, а PressEvent объектом.
Чтобы получить amount ожидаемое, вам нужно сделать это: <Button title='Add Amount' onPress={() => incrementByAmount(amount)}></Button> итак, вы получаете amount from useState .

Кроме того, вам определенно не нужно иметь три действия для вашего счетчика, более простым способом сделать это было бы иметь updateAmount функцию, которой вы передаете в качестве полезной нагрузки a type , которая была бы «increment» или «decrement», и an amount .
Еще более простым способом было бы иметь только сумму и передаватьлибо отрицательное, либо положительное значение для него.
Для ваших кнопок увеличения и уменьшения вам просто нужно передать 1 или -1 как amount .

Ваша вторая проблема заключается в том, что вы изменяете свое состояние в своем редукторе с = -= помощью операторов and .
Вот ваш фиксированный редуктор (я позволю вам реализовать изменения, которые я предложил ранее):

 import * as actionTypes from "../actionTypes";

const INITIAL_STATE = {
  counter: {
    counter1: 0,
    counter2: {
      innerCount: 0,
    },
  },
};

export const Auth = (state = INITIAL_STATE, action) => {
  const { type, payload } = action;

  switch (type) {
    case ActionTypes.INCREMENT_COUNTER_1:
      return {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1   1,
        },
      };
    case ActionTypes.DECREMENT_COUNTER_1:
      return {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1 - 1,
        },
      };
    case ActionTypes.INCREMENT_BY_AMOUNT:
      return {
        ...state,
        counter: {
          ...state.counter,
          counter1: state.counter.counter1   payload,
        },
      };
    default:
      return state;
  }
};

export default Auth;
 

Я удалил a переменную, которая не была нужна, и изменил = оператор на и -= оператор на - , чтобы ваше состояние не мутировало.

Ваша третья проблема заключается в том, что вы разрушаете переменную payload во время ее вызова amount в вашем action creator.
Также не забывайте, что вы получаете string от <TextInput> , а не number от .

Наконец, вы импортируете свои типы действий как actionTypes , но используете их как ActionTypes .

Комментарии:

1. После изменения проблемы с кнопкой я все еще получаю сообщение об ошибке ‘NaN’. Теперь я узнаю, как входное значение передается в качестве полезной нагрузки в действие. Кстати, спасибо за ваше предложение.

2. @dyee Я заметил еще несколько проблем, я отредактировал свой пост.