kouign_amann
kouign_amann

Reputation: 23

TypeError: Dispatch is not a Function in actions.js file

I'm working on a React-Redux app with Redux-thunk middleware. I'm getting an error that says: 'TypeError: Dispatch is not a function" when I try to to execute the function called removeStock() in my actions.js file:

action.js

export const deletePinnedStock = (user_id, stock_name, stock_id) => {
  return dispatch => {
    ApiService.delete("/users/" + user_id + "/stocks/" + stock_id)
    .then(response => {
      dispatch(removeStock(stock_name))
      console.log('here is the', response)
    }).catch((errors) => {
      console.log(errors)
    })
  }
}

removeStock() looks like this:

export const removeStock = (stock_name) => {
  return {
    type: 'REMOVE_PINNED_STOCK',
    stock_name: stock_name
  }
}

The case statement which corresponds to the 'REMOVE_PINNED_STOCK' action in my reducer looks like this:

reducer.js

  case 'REMOVE_PINNED_STOCK':
    return {
      ...state, 
      stocksData: {
      ...state.stocksData.delete((stock) => stock.name === action.stock_name)
      }
  }

I am not sure why I can't dispatch the removeStock() function within my deletePinnedStock() function. At other points in my action.js file I dispatch functions with no issue.

EDIT #1: deletePinnedStock is defined in my component like this:

stockCard.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { fetchPinnedStocks, deletePinnedStock, fetchStockData } from 
'../redux/modules/Stock/actions';
import '../styles/spin.css';
import Panel from 'react-uikit-panel';

class StockCard extends Component {

render() {
    const user_id = localStorage.getItem('currentUser_id') 
    const stock = this.props.stock //should be the stockObj keyed by name
    if (!stock) { 
        return null 
    } else {
    return (
        <Panel col='1-2' box title={stock.name} margin='bottom' context='primary'>
            <div>
                Open: {stock.openingPrice}
            </div>
            <div>
                Close: {stock.closingPrice}
            </div>
            <div>
                Low: {stock.low}
            </div>
            <div>
                High: {stock.high}
            </div>
            <div>
                Trading Volume: {stock.volume}
            </div>
            <button type="submit" 
            onClick={deletePinnedStock(user_id, stock.name, stock.id)}>Remove</button>
        </Panel>)
    }
  }
}

function mapStateToProps(state) {
  return {
    currentUser: state.auth.currentUser,
    stocksData: state.stock.stocksData 
  }
}

export default connect(mapStateToProps, { fetchPinnedStocks, 
deletePinnedStock, fetchStockData })(StockCard); 

Upvotes: 0

Views: 4771

Answers (1)

mpalmer
mpalmer

Reputation: 356

By calling deletePinnedStock directly, you're just calling it as a function, not dispatching it to the redux store. When you pass an action creator to connect(), it gets added as a prop to your component, and that prop is the one that is mapped to dispatch.

In short, replace

onClick={deletePinnedStock(user_id, stock.name, stock.id)}

with

onClick={this.props.deletePinnedStock(user_id, stock.name, stock.id)}

Upvotes: 1

Related Questions