I made an online store, but the counter for adding products to the cart does not work on production (everything works on localhost).
ProductHero.tsx (component code where the counter is):
import { useAppDispatch } from 'hooks/useRedux';
import { FC, useReducer, useState } from 'react';
import {
StyledBoxCounter,
StyledButton,
StyledContent,
StyledPrice,
StyledProductHero,
Wrapper,
} from './ProductHero.styles';
import { addProduct } from 'store';
import { ActionType, CountType, ProductHeroType } from 'types';
import { ActionTypes } from 'constants/index';
import SuccessInformation from 'components/molecules/SuccessInformation/SuccessInforamtion';
const reducer = (state: CountType, action: ActionType) => {
switch (action.type) {
case ActionTypes.Add:
return { count: state.count };
case ActionTypes.Subtract:
if (state.count === 1) return state;
else return { count: state.count-- };
case ActionTypes.Reset:
return { count: 1 };
default:
return state;
}
};
const ProductHero: FC<ProductHeroType> = (product) => {
const { cartImage, image, name, shortName, isNew, description, productPrice, price } = product;
const dispatch = useAppDispatch();
const [state, dispatchCounter] = useReducer(reducer, { count: 1 });
const [isOpen, setIsOpen] = useState(false);
const closeSuccesInformation = () => setIsOpen(false);
const toggleSuccesInformation = () => {
setIsOpen(true);
setTimeout(() => {
closeSuccesInformation();
}, 3000);
};
const handleAddProduct = () => {
dispatch(
addProduct({ image: cartImage, shortName, productPrice, quantity: state.count, price }),
);
dispatchCounter({ type: ActionTypes.Reset });
toggleSuccesInformation();
};
return (
<>
<SuccessInformation
name={name}
isOpen={isOpen}
closeSuccesInformation={closeSuccesInformation}
/>
<StyledProductHero>
<picture>
<source media='(min-width: 768px)' srcSet={image.desktop} />
<source media='(min-width: 500px)' srcSet={image.tablet} />
<img src={image.mobile} alt={`${name} image`} />
</picture>
<div>
{isNew && <h5>new product</h5>}
<h2>{name}</h2>
<StyledContent>{description}</StyledContent>
<StyledPrice>$ {productPrice}</StyledPrice>
<Wrapper>
<StyledBoxCounter>
<button onClick={() => dispatchCounter({ type: ActionTypes.Subtract })}>-</button>
<div>{state.count}</div>
<button onClick={() => dispatchCounter({ type: ActionTypes.Add })}> </button>
</StyledBoxCounter>
<StyledButton onClick={handleAddProduct}>add to cart</StyledButton>
</Wrapper>
</div>
</StyledProductHero>
</>
);
};
export default ProductHero;
live version: https://audiophile-ms.netlify.app/ github: https://github.com/Skolaczk/Audiophile/blob/main/src/components/organisms/ProductHero/ProductHero.tsx?fbclid=IwAR0rWOruteD9m6K0MbIc1szO7NAJGO5bOhjBu9ZPolKXwFZJhXWS1kZBxEM
I tried to debug the code for this component and it turned out to be a problem with the reducer but I'm not sure.
CodePudding user response:
It's because the way you set a new value on your reducer is incorrect in terms of what you're trying to do.
In JavaScript, the order really matters if you assign a variable with an increment operator. For example:
let a = 1;
b = a ; // b = 1
c = a; // c = 2
So in your case, when you click ( ) or (-) buttons, you always get the old value because the increment operator comes after the variable. So instead of put if after, just need to put it before the state.count
return { count: state.count };
For an explanation about this, you could look at this article, which explains in C/C but the concept is pretty much the same.