I am using React and Redux for my website and have ran into an issue. I have this card.
I can click on the left/right button to see the previous/next image like this: But Redux re-renders the component when I click on the /- button to change the quantity of the product which causes the image to be changed to the original one. What I want is to make the image stay as it is, but change the quantity at the same time.
There is a lot of code for me to post here, so I will post it on GitHub. This is the repo
I think the main files to look at are Shop.js
, ProductCard.js
, QuantityBox.js
and app/reducers/ProductSlice.js
This is the code that is responsible for updating the state:
import { createSlice } from "@reduxjs/toolkit";
export const ProductSlice = createSlice({
name: "products",
initialState: [
{id: 1, name: "Apple Watch 5", description: "some description", images: ["/product_images/product1_image1.jpeg", "/product_images/product1_image2.jpeg", "/product_images/product1_image3.jpeg"], price: 450, quantity: 0},
{id: 2, name: "Apple Watch 5", description: "some description", images: ["/product_images/product2_image1.jpeg", "/product_images/product2_image2.jpeg", "/product_images/product2_image3.jpeg"], price: 475, quantity: 0},
{id: 3, name: "Apple Watch 5", description: "some description", images: ["/product_images/product3_image1.jpeg", "/product_images/product3_image2.jpeg", "/product_images/product3_image3.jpeg"], price: 500, quantity: 0}
],
reducers: {
incrementQuantity: (state, action) => {
const product_id = action.payload
const product = state.find(product => product.id === product_id)
if(product){
product.quantity ;
}
},
decrementQuantity: (state, action) => {
const product_id = action.payload
const product = state.find(product => product.id === product_id)
if(product && product.quantity > 0){
product.quantity--;
}
}
}
})
export const selectProducts = state => state.products
export const {incrementQuantity, decrementQuantity} = ProductSlice.actions;
export default ProductSlice.reducer
CodePudding user response:
The problem is in your Shop
component. Every time, Shop
rerenders, you assign new unique key
properties to your ProductCard
components. That means that React doesn't find the old one, throws away the old component tree and builds up a completely new one - and resets all component's state in the process.
This is the code you have
<div id = "product-card-grid">
{products.map(product => {
return <ProductCard key = {uniqid()} product_id = {product.id} images = {product.images}/>
})}
</div>
and instead you should be using stable key
props:
<div id = "product-card-grid">
{products.map(product => {
return <ProductCard key = {product.id} product_id = {product.id} images = {product.images}/>
})}
</div>