#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 Я заметил еще несколько проблем, я отредактировал свой пост.