Home > Software engineering >  Redux is re-rendering a component when I don't want it to
Redux is re-rendering a component when I don't want it to

Time:07-16

I am using React and Redux for my website and have ran into an issue. I have this card. This is the product card

I can click on the left/right button to see the previous/next image like this: enter image description here 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. product image changes to the original one when I update the quanitity

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>
  • Related