简体   繁体   English

类型错误:props.addToCart 不是函数

[英]TypeError: props.addToCart is not a function

I am trying to dispatch my action when the client clicks the "addToCart" btn.当客户端单击“addToCart”btn 时,我试图调度我的操作。 which will add a new product to the cart, but i get the following error: "TypeError: props.addToCart is not a function".这会将新产品添加到购物车,但我收到以下错误:“TypeError:props.addToCart 不是函数”。 I am quite new to Redux and have learned the basics, but i cant seem to fix this problem.我对 Redux 还是很陌生并且已经学习了基础知识,但我似乎无法解决这个问题。

code cartActions:代码购物车操作:

import * as actions from '../constants/cartConstants'
import store from '../storeRedux'

console.log(store.getState())
//go through all the items and add the item with the specific id
//with getState we can get whatever exists in the redux store
export const addToCart = (product,qty,count) =>(dispatch)=> {
    let exists = false
    const cartItems = store.getState().cart.cartItems.slice()
    cartItems.forEach(item=> {
        if(item.id === product.id){
            exists = true
            item.qty++
            count++
            qty++
            
        }
    })
    if(!exists){
        cartItems.push({...product, count : 1, qty: 1})
    }
    dispatch({
        type: actions.ADD_TO_CART,
        payload: {cartItems}
    })
    localStorage.setItem("cartItems", JSON.stringify(cartItems))
}

export const removeFromCart = (product)=>(dispatch) =>{
    const cartItems = store.getState()
    .cart.cartItems.slice()
    .filter(
        x => x.id !== product.id
    )
    dispatch({
        type: actions.REMOVE_FROM_CART,
        payload: {cartItems}
    })
    localStorage.setItem("cartItems",JSON.stringify(cartItems))
}

export const adjustQty = (product,qty)=> (dispatch)=> {
    
    
    dispatch({
          type: actions.ADJUST_QTY,
        payload: {
            product,
            qty
        }
    })
  
}



export const reset =(cartItems,qty,count)=> (dispatch)=> {
    dispatch({
        type: actions.RESET,
        payload: {
            cartItems,
            qty,
            count
        }
    })
}

Code cartReducer:代码cartReducer:

import * as actions from '../constants/cartConstants'



const initialState = {
    cartItems: JSON.parse(localStorage.getItem("cartItems")) || [] , 
    count:0, 
    qty: 0,
    amount: 0
}

const shopReducer = (
    state = initialState,action)=> {
    switch(action.type){
        case actions.ADD_TO_CART:
            return{
                ...state,
                cartItems:action.payload.cartItems,
                count: action.payload.count,
                qty: action.payload.qty
               
            }
        case actions.REMOVE_FROM_CART:
            return  {
                ...state,
                cartItems:action.payload.cartItems,
                count: action.payload.count
                     }
               
        case actions.RESET:
            return{
                ...state,
                cartItems: action.payload.cartItems =[],
                qty: action.payload.qty =0,
                count: action.payload.count =0,
                amount: action.payload.amount =0
            }
        
        default:
            return state;
    }
}

export default shopReducer

Code productPage:代码产品页面:

import React, { useEffect } from 'react'
import Nav from '../components/nav'
import '../styles/productdetails.css'
import {connect} from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import { detailsProduct } from '../../actions/productActions'
import Review from '../components/review'
import { addToCart } from '../../actions/CartActions'




function ProductPage(props){

    //manage quantity product
    const productDetails = useSelector(state=> state.productDetails)
    const{product,loading,error} = productDetails
    const dispatch = useDispatch();
    const cart = useSelector(state=> state.cart)
    const {qty} = cart
    
    

    useEffect(()=> {
        dispatch(detailsProduct(props.match.params.id))
    }, [])
 
  
 
  






  
   
  
    return(
    
        <div>
            <Nav/>
            <a className="product-a" href="/store">Back to products</a>
       
            
    {loading? <div>loading...</div>: error? <div>{error}</div>: 
    (
        <div className="productpage">
         <div className="img" style={{background: `url(${product.img})`, backgroundSize: 'cover'}}></div>
         <div className="description">
         <h1>{product.name}</h1>
         <p>{product.description}</p>
         <span><small>€</small>{product.price}</span>
 
        <div className="amount">
         <p>Number:</p>  
        <label>
        <button type="button" className="btnInc" onClick={()=> {}}>+</button>
        <input type="number"step="1" min="1" value={qty} />    
        <button type='button' className="btnDec" onClick={()=> {}}>-</button>
        </label> 
        <div>Size: {product.size}</div>
         </div>
    
        {product.qty > 0? <button type="submit" className="addBtn" onClick={()=> {props.addToCart(product)}}> Add to cart</button> : <div>Out of stock</div>}
         
         </div>
 
         </div>
    
       

    
        
    )}
    <Review/>
    <div className="reviews">
        <h3>username</h3>
        <p>reviews : 3 out of 5</p>
        <p>description of what he says</p>
    </div>
</div>  
    )
}




export default connect(null,addToCart)(ProductPage)

You should do the following:您应该执行以下操作:

export default connect(null,{addToCart})(ProductPage)

According to the documentation the mapDispatchToProps parameter can either be a function or an object (or undefined).根据文档, mapDispatchToProps 参数可以是函数或对象(或未定义)。

If it is a function then it is expected to return an object and each property of that object is expected to be a function that can be called by your component to dispatch an action.如果它是一个函数,那么它应该返回一个对象,并且该对象的每个属性都应该是一个可以由您的组件调用以调度操作的函数。

If it is an object then each property of that that object should be a function that returns an action (action creator).如果它是一个对象,那么该对象的每个属性都应该是一个返回动作(动作创建者)的函数。 Connect will replace that function with a function that will pass arguments to the action creator and dispatches the resulting action. Connect 将用一个函数替换该函数,该函数将参数传递给动作创建者并分派结果动作。

So {addToCart} is shorthand for: {addToCart: addToCart} which is an object with an addTocart property that has a value of the action creator named addToCart .所以{addToCart}是: {addToCart: addToCart}简写,它是一个具有addTocart属性的对象,它具有名为addToCart的动作创建者的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM