I am creating a cart page for an ecommerce site.
I am using redux for state management and react-query for data management. I am new in redux and react-query. I am facing some problem while updating localStorage.
Redux initially setting cartItem from localStorage. But the problem occurs when I try to remove a item from the cart. When I click on remove button react-query trigger isLoading. I try to use isFetching but it did the same. How can I fix that?
Cart Page
const CartPage = () => {
const { cartItems } = useSelector((state) => state.cart);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (cartItems.length > 0) {
setLoading(false);
}
}, [cartItems]);
const ids = cartItems.map((item) => item.id);
const {
data: cartData,
isLoading,
isError,
error,
status,
isFetching
} = useQuery(["cart", ids], () => getCartItems(ids), {
staleTime: Infinity
});
if (loading || isLoading) {
console.log("Fetching data...");
return <p>Loading...</p>;
}
return (
<div className="container">
{
!cartItems.length
? <div className="cart-empty">
<h2 className="cart-empty__title">Your cart is empty</h2>
<Link href="/shop" className="btn btn-primary">Go To Shop</Link>
</div>
: <div>
<div className="cart-details-main-block" id="dynamic-cart">
{Children.toArray(
cartData.map((item) => {
return <CartProduct {...item} />;
})
)}
</div>
</div>
</div>
}
</div>
</div>
);
};
CartProduct
export default function CartProduct({ _id, title, price, image }) {
const dispatch = useDispatch();
// remove item from cart and update the cart ui
const handleRemoveFromCart = (id) => {
dispatch(removeItemFromCart({ id }));
}
return (
<div className="cart-product cart-product--main">
{/* .product-quantity-block starts */}
<div className="total-block pl-7 pl-xs-0">
<div className="total-block-inner">
<h3 className="price-text">
$140
</h3>
<button onClick={() => handleRemoveFromCart(_id)}>
✖
</button>
</div>
</div>
</div>
)
}
cartSlice
import { createSlice } from '@reduxjs/toolkit';
const CART_KEY = 'cart';
// Load cart data from local storage
const loadCartFromStorage = () => {
if (typeof window !== 'undefined') {
const cartData = localStorage.getItem(CART_KEY);
if (cartData) {
return JSON.parse(cartData);
}
}
return { cartItems: [] };
};
// Save cart data to local storage
const saveCartToStorage = (cartData) => {
if (typeof window !== 'undefined') {
localStorage.setItem(CART_KEY, JSON.stringify(cartData));
}
};
// Define the cart slice
const cartSlice = createSlice({
name: 'cart',
initialState: loadCartFromStorage(),
reducers: {
addItemToCart: (state, action) => {
// Check if the item already exists in the cart
const itemIndex = state.cartItems.findIndex((item) => item.id === action.payload.id);
if (itemIndex >= 0) {
// If the item already exists, update the quantity
state.cartItems[itemIndex].quantity += action.payload.quantity;
} else {
// If the item doesn't exist, add it to the cart
state.cartItems.push(action.payload);
}
// Save the cart data to local storage
saveCartToStorage(state);
},
removeItemFromCart: (state, action) => {
// Remove the item from the cart
state.cartItems = state.cartItems.filter((item) => item.id !== action.payload.id);
// Save the cart data to local storage
saveCartToStorage(state);
},
},
});
// Export the actions
export const { addItemToCart, removeItemFromCart } = cartSlice.actions;
// Export the reducer
export default cartSlice.reducer;