Search code examples
reduxreact-reduxdispatch

How can I fix type Error as I am just trying to add an item


I am working with redux and I have my actionCreator to add to cart also my reducer function which are below but I keep getting error message which says "actionCreators.js:44 Uncaught TypeError: dispatch is not a function"

My Reducer

import { ADD_TO_CART } from '../action/types';

const init = [];
const addToCartReducer = (state = init, action) => {
  switch (action.type) {
    case ADD_TO_CART:
      return [...state, ...action.payload];

    default:
      return state;
  }
};

export default addToCartReducer;

My Action Creator

export const addToCart = (item) => (dispatch) => {
  const product = { ...item, count: 1, sum: item.count * item.prices[0].amount };
  dispatch({
    type: ADD_TO_CART,
    payload: product,
  });
};

Component where I am using it

import React, { Component } from 'react';

class Products extends Component {
  constructor(props) {
    super(props);
    this.state = '';
  }

  render() {
    const {
      products, addProductImage, centered, imageContainer, currency, addToCart, **Passed it as props**
    } = this.props;
    const allProducts = !products ? '' : products.products.map((product) => (
      <article className="card" key={product.id}>
        <div style={imageContainer}>
          <img className="card_image1" src={product.gallery[0]} alt={product.name} />
          {product.inStock ? (
            <img
              src={addProductImage}
              alt={product.name}
              style={{ cursor: 'pointer' }}
              onClick={addToCart(product)} **Here I call it** 
            />
          )
            : null}
          {!product.inStock ? (<div style={centered}>Out of stock</div>) : null}
        </div>
        <div>
          <div>{product.name}</div>
          <div>{`${currency} ${product.prices[0].amount}`}</div>
        </div>
      </article>
    ));
    return (
      <>{allProducts}</>
    );
  }
}

export default Products;

But I get this error message

Error message

I have tried to use it without props, I mean by calling it direct to that component but to no progress.


Solution

  • the actionCreator is a function that returns an action

    export const addToCart = (product) => ({
        type: ADD_TO_CART,
        payload: product,
    });
    

    Now to call the action creator in class component you need to use the connect function from redux

    import React, { Component } from 'react';
    
    class Products extends Component {
      constructor(props) {
        super(props);
        this.state = '';
      }
    
      render() {
        const {
          products, addProductImage, centered, imageContainer, currency, addToCart, **Passed it as props**
        } = this.props;
        const allProducts = !products ? '' : products.products.map((product) => (
          <article className="card" key={product.id}>
            <div style={imageContainer}>
              <img className="card_image1" src={product.gallery[0]} alt={product.name} />
              {product.inStock ? (
                <img
                  src={addProductImage}
                  alt={product.name}
                  style={{ cursor: 'pointer' }}
                  onClick={() => addToCart({ ...product, count: 1, sum: product.count * product.prices[0].amount })}
                />
              )
                : null}
              {!product.inStock ? (<div style={centered}>Out of stock</div>) : null}
            </div>
            <div>
              <div>{product.name}</div>
              <div>{`${currency} ${product.prices[0].amount}`}</div>
            </div>
          </article>
        ));
        return (
          <>{allProducts}</>
        );
      }
    }
    
     const mapDispatchToProps = {
          addToCart,
        }
     export default connect(null, mapDispatchToProps)(Products);
    

    Reducer

    import { ADD_TO_CART } from '../action/types';
    
    const init = [];
    const addToCartReducer = (state = init, action) => {
      switch (action.type) {
        case ADD_TO_CART:
          return [...state, action.payload];
    
        default:
          return state;
      }
    };
    
    export default addToCartReducer;