I'm having issues adding product to cart in react,it's my first time to implement something of this nature. Here is the code I have
const data = {
productData:[
{
id: 1,
image: "/assets/images/shop/product.jpeg",
name: "product1",
},
{
id: 2,
image: "/assets/images/shop/product.jpeg",
name: "product2",
},
{
id: 3,
image: "/assets/images/shop/product.jpeg",
name: "product3"
},
]
}
export default data
import React from 'react'
import {connect} from 'react-redux'
import { addToCart } from '../../../redux/actions/cart-action'
import { Card, Button, Container } from 'react-bootstrap'
import "../shop.css"
function ProductCard(props) {
return (
<div className="product-card col-sm-12 col-md-4 col-lg-3 pb-5">
<div className="col-md-12 product overflow-hidden h-100 shadow-lg">
<img className="product-img card-img-top img-fluid" src={props.image} alt="product" />
<div className="text-center">
<div>{props.name}</div>
<div> {props.id} </div>
<div> {props.desc} </div>
<div>#{props.price} </div>
<button className="btn btn-success mb-2" onClick={() => dispatch(addToCart(props.id))}>Add to Cart</button>
</div>
</div>
</div>
)
}
const mapDispatchToProps = (dispatch) =>{
return{
addToCart: (id) => dispatch(addToCart(id))
}
}
export default connect (null, mapDispatchToProps) (ProductCard)
//Product List
const ProductList = ({products}) => {
console.warn(data.productData)
return (
<div className='shop'>
<h1 className="text-center">All products</h1>
<div className="row">
<div className="col-md-10 col-12">
<section className="mx-4 py-4">
<div className="row align-items-center justify-content-center">
{data.productData.map((product, index) =>{
return(
<ProductCard addToCard={addToCart} image={product.image} name={product.name} desc={product.desc} price={product.price} key={index} />
)
})}
</div>
</section>
</div>
<div className="col-2">
<div className="container product-aside d-none d-sm-block py-4">Blah blah Blah . . ./div>
</div>
</div>
</div>
)
}
const mapStateToProps = state =>{
return{
products: state.cart.products,
}
}
export default connect(mapStateToProps) (ProductList)
And i have the following in the redux store
//REDUX
cart-action.js
export const addToCart = (product_id) =>{
console.log(product_id)
return{
type: ADD_TO_CART,
payload:{
id: product_id,
}
}
}
cart-reducer.js
const initialState = {
products: [],
cart: [],
currentItem: null
};
const cartReducer = (state = initialState, action) =>{
switch(action.type){
case ADD_TO_CART:
const item = state.products.find(product => product.id === action.payload.id);
const inCart = state.cart.find(item => item.id ===action.payload.id ? true: false);
return{
...state,
cart: inCart ? state.cart.map(item => item.id ===action.payload.id ? {...item, qty: item.qty 1} : item) : [...state, {...item, qty: 1}]
}
default:
return state;
}
}
export default cartReducer
The error I'm getting is:
TypeError: addToCart is not a function onClick
Please I need some help to fix this. I have been trying to fix it but I keep running into one problem after another
CodePudding user response:
Looks like the addToCart is not recognize Why not just pass the addToCart function on props like this
<ProductCard addCart={addToCart}>
CodePudding user response:
I don't know why you are passing addToCart as ProductCard(props, {addToCart}) in ProductCard function. Rather than using dispatch() method you can directly call addToCart action onClick event. Please try this solution and let me know if it worked
import addToCart from './cart-action.js'
export default function ProductCard(props) {
return (
<div className="product-card col-sm-12 col-md-4 col-lg-3 pb-5">
<div className="col-md-12 product overflow-hidden h-100 shadow-lg">
<img className="product-img card-img-top img-fluid" src={props.image} alt="product" />
<div className="text-center">
<div>{props.name}</div>
<div> {props.id} </div>
<div> {props.desc} </div>
<div>#{props.price} </div>
<button className="btn btn-success mb-2" onClick={() => dispatch(addToCart(props.id))}>Add to Cart</button>
</div>
</div>
</div>
)
}
Here is the simple example
import React from 'react'
import { useDispatch } from 'react-redux'
export const CounterComponent = ({ value }) => {
const dispatch = useDispatch()
return (
<div>
<span>{value}</span>
<button onClick={() => dispatch({ type: 'increment-counter' })}>
Increment counter
</button>
</div>
)
}