首页 > 解决方案 > TypeError:props.addToCart 不是函数

问题描述

当客户端单击“addToCart”btn 时,我正在尝试调度我的操作。这会将新产品添加到购物车,但我收到以下错误:“TypeError:props.addToCart 不是函数”。我对 Redux 很陌生,并且已经学习了基础知识,但我似乎无法解决这个问题。

代码购物车动作:

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
        }
    })
}

代码购物车减速器:

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

代码产品页面:

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>€&lt;/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)

标签: javascriptreactjsredux

解决方案


您应该执行以下操作:

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

根据文档, mapDispatchToProps 参数可以是函数或对象(或未定义)。

如果它是一个函数,那么它应该返回一个对象,并且该对象的每个属性都应该是一个函数,您的组件可以调用它来调度一个动作。

如果它是一个对象,那么该对象的每个属性都应该是一个返回动作的函数(动作创建者)。Connect 将用一个函数替换该函数,该函数将参数传递给动作创建者并调度结果动作。

{addToCart}简写也是如此:{addToCart: addToCart}这是一个具有属性的对象,该addTocart属性具有名为的动作创建者的值addToCart


推荐阅读