Reputation: 4054
I am trying to create quantity field where user can increase and decrease the quantity. I am binding this field with redux form
. There is an issue where if i keep on increasing it increases the number but when after increasing the number if i try to decrease the number it first increases and in second decrease it starts to decrease the number. When decreasing if the number is reached to the point of 1 then if i try to increase the number it will show 0 and then starts working in an expected way.
Here is the demo as well
https://codesandbox.io/s/little-lake-q3rw9
here is the source code
const QuantityField = ({ input, label, meta, inputCss, labelCss, ...rest }) => {
const [quantity, setQuantity] = React.useState(1);
const handleIncrease = () => {
setQuantity(quantity + 1);
console.log("###################");
rest.change(input.name, quantity);
console.log("###################");
console.log("input value", input.value);
};
const handleDecrease = () => {
if (quantity > 0) {
setQuantity(quantity - 1);
rest.change(input.name, quantity);
}
};
return (
<>
<InputWrapper>
{label && (
<Label isActive={meta !== undefined && meta.active} css={labelCss}>
{label}
</Label>
)}
<TextInputWapper>
<Augment onClick={() => handleIncrease()}>
<FontAwesomeIcon icon={faPlus} style={{ color: "#fff" }} />
</Augment>
<TextInput
css={inputCss}
disabled
isActive={meta !== undefined && meta.active}
hasError={meta !== undefined && meta.touched && !!meta.error}
{...input}
{...rest}
/>
<Augment onClick={() => handleDecrease()}>
<FontAwesomeIcon icon={faMinus} style={{ color: "#fff" }} />
</Augment>
</TextInputWapper>
{meta !== undefined && meta.touched && !!meta.error && (
<Error className="field-error">{meta.error}</Error>
)}
</InputWrapper>
</>
);
};
export default QuantityField;
const Augment = styled.span`
background: #1ab394;
display: flex;
align-items: center;
justify-content: center;
padding: 0.375rem 0.75rem;
cursor: pointer;
`;
Upvotes: 0
Views: 668
Reputation: 5600
My Code is:- Actions
import { MINUS_NUMBER, PLUS_NUMBER, RESET_NUMBER } from "./types";
export const minusAction = number => dispatch => {
dispatch({
type: MINUS_NUMBER,
payload: number
});
};
export const plusAction = number => dispatch => {
dispatch({
type: PLUS_NUMBER,
payload: number
});
};
export const resetAction = number => dispatch => {
dispatch({
type: RESET_NUMBER,
payload: number
});
};
Reducer
const addNumber = (state = initialState, action) => {
switch (action.type) {
case MINUS_NUMBER:
return {
...state,
number: action.payload - 1
};
case PLUS_NUMBER:
return {
...state,
number: action.payload + 1
};
case RESET_NUMBER:
return {
...state,
number: 0
};
default:
return state;
}
};
export default addNumber;
Root Reducer
import { combineReducers } from "redux";
import clickerReducer from "./clickerReducer";
export default combineReducers({
clickerReducer
});
component
import React from "react";
import { connect } from "react-redux";
import { minusAction, plusAction, resetAction } from "../actions/clickerAction";
function App(props) {
return (
<div align="center" className="App">
<h1>{props.number}</h1>
<button
onClick={() => {
props.minusAction(props.number);
}}
>
-
</button>
<button
onClick={() => {
props.resetAction(props.number);
}}
>
Reset
</button>
<button
onClick={() => {
props.plusAction(props.number);
}}
>
+
</button>
</div>
);
}
const mapStateToProps = state => ({
number: state.clickerReducer.number
});
export default connect(mapStateToProps, {
minusAction,
plusAction,
resetAction
})(App);
Upvotes: 0
Reputation: 5476
The problem here is you are changing values just after setQuantity
which is asynchronous so your next statement will not have the updated value instead you need to use useEffect
to notify you the quantity
value changes and then update/change your values
const QuantityField = ({ input, label, meta, inputCss, labelCss, ...rest }) => {
const [quantity, setQuantity] = React.useState(0);
const handleIncrease = () => {
setQuantity(quantity + 1);
console.log("###################");
// rest.change(input.name, quantity);
console.log("###################");
console.log("input value", input.value);
};
const handleDecrease = () => {
if (quantity > 0) {
setQuantity(quantity - 1);
console.log("sss", quantity);
}
};
React.useEffect(() => {
rest.change(input.name, parseInt(quantity,10));
}, [quantity]);
here is the sandbox link https://codesandbox.io/s/compassionate-mestorf-r0qyt
Upvotes: 1