Search code examples
reactjsreduxreact-propsdispatch

mapDispatchToProps not working. this.props.getCategories is not a function


I am trying to get a list of categories from backend using react-redux looks like things are fine unless the dispatch function calls. I just used a tutorial from youtube in this link by Traversy Media

Reducer

import { GET_CATEGORIES } from '../actions/types.js';

const initialState = {
    categories: []
}

export default function(state = initialState, action){
    switch(action.type){
        case GET_CATEGORIES:
            return {
                ...state,
                categories: action.payload
            };
        default:
            return state;

    }
}

Action:

import axios from "axios";

import { GET_CATEGORIES } from "./types";

//GET CATEGORIES
export const getCategories = () => dispatch => {
    axios.get('/api/categories/')
        .then(res => {
            dispatch({
                type: GET_CATEGORIES,
                payload: res.data
            });
        }).catch(err => console.log(err));
};

Component:

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { getCategories } from '../actions/categories';

export class Categories extends Component {
    static propTypes = {
        categories: PropTypes.array.isRequired
    }

    componentDidMount() {
        this.props.getCategories();  //no error when comment this line
    }

    render() {
        return(
            <div>
                <h1>
                    Categories Component
                </h1>
            </div>
        )
    }
}

const mapStateToProps = state => ({
    categories: state.categories.categories
})

export default connect(mapStateToProps, { getCategories })(Categories);

if I comment the line in the componentDidMount then page loads with an empty array in the redux store but if I try to call the action to actually get data, I get the following errors:

Uncaught TypeError: this.props.getCategories is not a function

EDIT:

I import Category component in App.js this way:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from '../store';
import {Categories} from './Categories';

class App extends Component{
    render() {
        return (
            <Provider store={store}>
                <Categories />
            </Provider>
        )
    }
}

ReactDOM.render(<App />, document.getElementById('app'));

also I found I get the below warning from webpack:

WARNING in ./prj/frontend/src/components/Categories.js 63:17-30
export 'default' (imported as 'getCategories') was not found in '../actions/categories' (possible exports: getCategories)
 @ ./prj/frontend/src/components/App.js 27:0-42 45:42-52
 @ ./prj/frontend/src/index.js 1:0-35

Solution

  • Don't see any problem with the provided code, my guess is that you wrongly imported a non connected component:

    // WRONG, you import non-connected component
    import {Categories} from 'Categories.js'
    
    // Your default export is wrapped with connect
    import Categories from 'Categories.js';