Nested array in Context React won't update its state

Viewed 100

I'm building a e-commerce store where I have the following data structure:

productsData.js

export const storeProducts = [
  {
        id: 1,
        title: "Santos",
        img: "img/pfs - black.png",
        price: 59.70,
        description: "Lorem Ipsum",
        gender: ["Feminine", "Masculine"],
        info:
            "Lorem Ipsum",
        inCart: false,
        count: 0,
        total: 0    
    } 
];


export const detailProducts = {
          id: 1,
          title: "Pecadores Feitos Santos",
          img: "img/pfs - black.png",
          price: 59.70,
          description: "Lorem ipsum",
          gender: ["Feminine", "Masculine"],
          info:
              "Lorem ipsum.",
          inCart: false,
          count: 0,
          total: 0  
    };

I have a Context React file that is my provider and consumer:

context.js

import React, { Component } from 'react'
import { storeProducts, detailProducts } from './productsData';

const ProductContext = React.createContext();
// Provider and Consumer

class ProductProvider extends Component {
  state = {
      products: [],
      detailProducts: detailProducts,
      cart: [],
      modalOpen: false,
      modalProduct: detailProducts,
      cartTotal: 0
  };

  componentDidMount() {
    this.setProducts();
  }


  setProducts = () => {
    let tempProducts = [];
    storeProducts.forEach(item => {
      const singleItem = {...item};
      tempProducts = [...tempProducts, singleItem];
    });
      this.setState(() => {
        return { products: tempProducts };
        // console.log("State products: ", storeProducts[0].color[0])
      });
    };
    
    getItem = id => {
      const product = this.state.products.find(item => item.id === id);
    return product;
  };

  handleDetail = id => {
    const product = this.getItem(id);
    this.setState(() => {
      return { detailProducts: product };
    });
  };

  addToCart = id => {
    let tempProducts = [...this.state.products];
    const index = tempProducts.indexOf(this.getItem(id));
    const product = tempProducts[index];
    // console.log(product.gender);
    product.inCart = true;
    product.count = 1;
    const price = product.price;
    product.total = price;
    this.setState(() => {
      return { products: tempProducts, cart: [...this.state.cart,product] }
    }, () => { this.addTotal();});
  }

  openModal = id => {
    const product = this.getItem(id);
    this.setState(() => {
      return {modalProduct: product, modalOpen: true}
    })
  }

  closeModal = () => {
    this.setState(() => {
      return {modalOpen: false}
    })
  }

  increment = (id) => {
    let tempCart = [...this.state.cart];
    const selectedProduct = tempCart.find(item => item.id === id);
    const index = tempCart.indexOf(selectedProduct);
    const product = tempCart[index];

    product.count = product.count + 1;
    product.total = product.count * product.price;

    this.setState(() => {
      return {
        cart: [...tempCart]
      }
    }, () => { this.addTotal() })
  }

  decrement = (id) => {
    let tempCart = [...this.state.cart];
    const selectedProduct = tempCart.find(item => item.id === id);
    const index = tempCart.indexOf(selectedProduct);
    const product = tempCart[index];

    product.count = product.count - 1;

    if(product.count === 0) {
      this.removeItem(id);
    }
    else {
      product.total = product.count * product.price;
      this.setState(() => {
        return {
          cart: [...tempCart]
        }
      }, () => { this.addTotal() })
    }
  }

  removeItem = (id) => {
    let tempProducts = [...this.state.products];
    let tempCart = [...this.state.cart];

    tempCart = tempCart.filter(item => item.id !== id);
    const index = tempProducts.indexOf(this.getItem(id));
    let removedProduct = tempProducts[index];
    removedProduct.inCart = false;
    removedProduct.count = 0;
    removedProduct.total = 0;

    this.setState(() => {
      return {
        cart:[...tempCart],
        products: [...tempProducts]
      }
    }, ()=> {
      this.addTotal();
    })
  }

  clearCart = () => {
    this.setState(() => {
      return { cart: [] };
    }, () => {
      this.setProducts();
      this.addTotal();
    })
  }

  addTotal = () => {
    let total = 0;
    this.state.cart.map(item => (total += item.total));
    this.setState(() => {
      return {
      cartTotal: total
      }
    })
  }
  
  render() {
    return ( 
      <ProductContext.Provider value={{
        ...this.state,
        handleDetail: this.handleDetail,
        addToCart: this.addToCart,
        openModal: this.openModal,
        closeModal: this.closeModal,
        increment: this.increment,
        decrement: this.decrement,
        removeItem: this.removeItem,
        clearCart: this.clearCart
      }}
      >
        {this.props.children}
      </ProductContext.Provider>

    )
  }  
}

const ProductConsumer = ProductContext.Consumer;

export { ProductProvider, ProductConsumer };

Everything works just fine, but here's where the problems start:

Details.js

import React, { Component } from 'react';
import { ProductConsumer } from '../context';
import { Link } from 'react-router-dom';
import { ButtonContainerSecondary } from './ButtonSecondary';
import { ButtonDetails } from './ButtonDetails';
import { ColorButton } from './ColorButton';
import PropTypes from 'prop-types';

export default class Details extends Component {
  render() {
    return (
      <ProductConsumer>
        {value => {
        const {id, img, price, description, color, gender, info, title, inCart} = value.detailProducts;
        return (
          <div className="container pb-5">
            <div className="row">
              <div className="col-10 mx-auto text-center text-slanted my-5">
{gender.map((item, key) => (
                  <span>{" "}<ButtonDetails key={key} onClick={() => { this.setState({gender: key}); console.log(key)}}
              </div>
            </div>
          </div>
        )
        }}
      </ProductConsumer>
    )
  }
}

Details.propTypes = {
  product: PropTypes.shape({
    color: PropTypes.arrayOf(PropTypes.string),
    gender: PropTypes.arrayOf(PropTypes.string)
  })
}

I can't seem to figure out how to pass in the state in the nested array gender to the next level. I do get the console.log(key) right, but it gets lost as I move up to the cart. I would like to give the user the chance to choose from a feminine or masculine shirt:

CartItem.js

import React from 'react'

export default function CartItem({ item, value }) {
  const {id, title, img, price, gender, total, count} = item;
  const {increment, decrement, removeItem} = value; 
  
  return (
   
        <div className="col-10 mx-auto col-lg-2">
            <span className="d-lg-none">Product: </span> {title} {gender} {console.log(gender)}
        </div>
  );
}

Here the console.log(gender) returns both items of the array altogether ("FeminineMasculine").

I'm a newbie and would really appreciate your help. Sorry if anything!

0 Answers
Related