我刚刚开始学习 React 并学习如何使用 Context Api。当用户点击产品页面上的添加到购物车按钮时,我试图更新我的购物车,但由于某种原因它不会更新状态。
这是我的代码:
上下文 API:
import React, { createContext, useEffect, useState } from 'react';
import { detailProduct, storeProducts } from './data';
const ProductContext = createContext();
const ProviderContext = ({ children }) => {
const [products, setProducts] = useState({
product: [],
detailsProduct: detailProduct,
cart: [],
modalOpen: false,
modalProduct: detailProduct,
});
const { product, detailsProduct, cart, modalOpen, modalProduct } = products;
const newProducts = () => {
let tempProducts = [];
storeProducts.forEach((item) => {
const singleItem = { ...item };
tempProducts = [...tempProducts, singleItem];
});
setProducts({
...products,
product: tempProducts,
});
};
useEffect(() => {
newProducts();
}, []);
const getItem = (id) => {
const singleProduct = product.find((item) => item.id === id);
return singleProduct;
};
const handleDetail = (id) => {
const newProduct = getItem(id);
setProducts({ ...products, detailsProduct: newProduct });
};
const addToCart = (id) => {
let tempProducts = [...product];
const index = tempProducts.indexOf(getItem(id));
const cartProduct = tempProducts[index];
cartProduct.inCart = true;
cartProduct.count = 1;
const price = cartProduct.price;
cartProduct.total = price;
setProducts({
...products,
product: tempProducts,
cart: [...cart, cartProduct],
});
console.log(products);
};
const openModal = (id) => {
const product = getItem(id);
setProducts({ ...products, modalProduct: product, modalOpen: true });
console.log(products);
};
const closeModal = () => {
setProducts({ ...products, modalOpen: false });
};
return (
<ProductContext.Provider
value={{
...products,
handleDetail: handleDetail,
addToCart: addToCart,
openModal: openModal,
closeModal: closeModal,
}}
>
{children}
</ProductContext.Provider>
);
};
const ConsumerContext = ProductContext.Consumer;
export { ProviderContext, ConsumerContext };
我的产品页面:
import React, { Fragment } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { ConsumerContext } from '../Context';
import PropTypes from 'prop-types';
const Product = ({ product }) => {
const { id, title, img, price, inCart } = product;
return (
<ProductWrapper className='col-9 mx-auto col-md-6 col-lg-3 my-3'>
<div className='card'>
<ConsumerContext>
{(value) => (
<div
className='img-container p-5'
onClick={() => value.handleDetail(id)}
>
<Link to='/details'>
<img src={img} alt='product' className='card-img-top' />
</Link>
<button
className='cart-btn'
disabled={inCart ? true : false}
onClick={() => {
value.addToCart(id);
value.openModal(id);
}}
>
{inCart ? (
<p className='text-capitalize mb-0' disabled>
in cart
</p>
) : (
<i className='fas fa-cart-plus'></i>
)}
</button>
</div>
)}
</ConsumerContext>
<div className='card-footer d-flex justify-content-between'>
<p className='align-self-center mb-0'>{title}</p>
<h5 className='tex-blue font-italic mb-0'>
<span className='mr-1'>$</span>
{price}
</h5>
</div>
</div>
</ProductWrapper>
);
};
export default Product;
我还在产品详细信息页面上使用了 onClick 元素,由于某种原因它可以工作,而产品页面上的元素却不起作用。这是产品详细信息代码:
import React from 'react';
import { ConsumerContext } from '../Context';
import { Link } from 'react-router-dom';
import { ButtonContainer } from './Button';
const ProductDetails = () => {
return (
<ConsumerContext>
{(value) => {
const { id, company, img, info, price, title, inCart } =
value.detailsProduct;
return (
<div className='container py-5'>
{/* {title} */}
<div className='row'>
<div className='col-10 mx-auto text-center text-slanted text-blue my-5'>
<h1>{title}</h1>
</div>
</div>
{/* {title} */}
{/* {product info} */}
<div className='row'>
<div className='col-10 mx-auto col-md-6 my3'>
<img src={img} alt='product' className='img-fluid' />
</div>
{/* {product text} */}
<div className='col-10 mx-auto col-md-6 my3 text-capitalize'>
<h2>model : {title}</h2>
<h4 className='text-title text-uppercase text-muted mt-3 mb-2'>
made by : <span className='text-uppercase'>{company}</span>
</h4>
<h4 className='text-blue'>
<strong>
price : <span>$</span>
{price}
</strong>
</h4>
<p className='text-capitalize font-weight-bold mt-3 mb-0'>
about product:
</p>
<p className='text-muted lead'>{info}</p>
{/* {buttons} */}
<div>
<Link to='/'>
<ButtonContainer>back to products</ButtonContainer>
</Link>
<ButtonContainer
cartButton
disabled={inCart ? true : false}
onClick={() => {
value.addToCart(id);
// value.openModal(id);
}}
>
{inCart ? 'in cart' : 'add to cart'}
</ButtonContainer>
</div>
</div>
</div>
</div>
);
}}
</ConsumerContext>
);
};
export default ProductDetails;