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!