简体   繁体   中英

How to fix: 'TypeError: fetchProducts is not a function'

I am trying to retrieve a set of products from an API using a redux store.

To achieve this, I created actions and reducers, a function mapStateToProps() and a function mapDispatchToProps() , the latter one contains a function fetchProducts() , which is defined in the action file and should retrieve the list of products when called.

All of this is done in the following way:

This is the overview component, which should render the data (the actual rendering is left out, because it does not affect this question):

import React, {Component} from 'react';
import {connect} from 'react-redux';
import PropTypes from 'prop-types'
import fetchProductsAction from '../actions/ProductFetchingActionFile'
import {bindActionCreators} from 'redux';

export class Overview extends Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        this.props.fetchProducts();
    }

    render() {
        return(
                  <h1>test</h1>
        )
    }
}

const mapStateToProps = state => ({
    error: state.rootReducer.productsReducer.error,
    products: state.rootReducer.productsReducer.products,
    pending: state.rootReducer.productsReducer.pending,
})

const mapDispatchToProps = dispatch => bindActionCreators({
    fetchProducts: fetchProductsAction 
}, dispatch)

Overview.propTypes = {
    fetchProducts: PropTypes.func
}

export default connect(mapStateToProps, mapDispatchToProps)(Overview);

This is the action file (ProductFetchingActionFile):

import {
    PREFIX,
    FETCH_PRODUCTS_PENDING,
    FETCH_PRODUCTS_SUCCESS,
    FETCH_PRODUCTS_ERROR
} from "./types";

function fetchProductsPending() {
    return{
        type: FETCH_PRODUCTS_PENDING
    }
}

function fetchProductsSuccess(products) {
    return{
        type: FETCH_PRODUCTS_SUCCESS,
        products: products
    }
}

function fetchProductsError(error) {
    return{
        type: FETCH_PRODUCTS_ERROR,
        error: error
    }
}

function fetchProducts() {
    return dispatch => {
        dispatch(fetchProductsPending());
        return fetch(`localhost:8080/products`)
            .then(res => res.json())
            .then(res => {
                if(res.error) {
                    throw(res.error);
                }
                dispatch(fetchProductsSuccess(res));
                return res
            })
            .catch(error => {
                dispatch(fetchProductsError(error));
            })
    }
}

export default fetchProducts

This is the reducer file:

import {
    FETCH_PRODUCTS_PENDING,
    FETCH_PRODUCTS_SUCCESS,
    FETCH_PRODUCTS_ERROR
} from "./types"


const initialState = {
    pending: false,
    products: [],
    error: null
}

export function productsReducer(state = initialState, action) {
    switch(action.type) {
    case FETCH_PRODUCTS_PENDING:
        return {
            ...state,
            pending: true
        }
    case FETCH_PRODUCTS_SUCCESS:
        return {
            ...state,
            pending: false,
            products: action.products
        }
    case FETCH_PRODUCTS_ERROR:
        return {
            ...state,
            pending: false,
            error: action.error
        }
    default:
        return state;
    }
}

Now, I get the following error when the Overview component is loaded: TypeError: fetchProducts is not a function . This error fires on the call to fetchProducts in the componentDidMount() function.

Also, when the Overview.props is printed in the console before this call, it does not contain the function fetchProducts , so I suspect that it has to do something with the mapDispatchToProps , but I cannot find the problem.

Edit: it is good to note that if the imported fetchProductsAction is printed in the constructor of the Overview component, it shows the correct function. It does however not end up in the props of Overview , so I expect the problem to be there.

try this

   const mapDispatchToProps = dispatch => {
       fetchProducts : () => {
            dispatch(fethcProducts())
         }
   }

You're importing your action as

import fetchProductsAction from '../actions/ProductFetchingActionFile'

when it looks like it's not being exported as a default.

It should probably be:

import { fetchProductsAction } from '../actions/ProductFetchingActionFile'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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