Alexey Alpatov
Alexey Alpatov

Reputation: 154

Why my "mapDispatchToProps" does not see my action function?

Please tell me why, when I call this.props.getOnEvents(), an error occurs that “getOnEvents() is not a function”, what’s wrong here and how to fix it? I’m looking at the console.log and there is this function in the props, but when I try to call, an error flies out that it’s not a function

EventCalendar.js

import React, { Component } from 'react';
import { withStyles } from '@material-ui/core/styles';
import EventCalendarTable from './EventCalendarTable';
import EventCalendarView from './EventCalendarView';

const styles = theme => ({
  root: {
    width: '80%',
    margin: '20px auto 0'
  },
});

class EventCalendar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      viewEvents: 'table'
    };
  }

  componentDidMount() {
    this.props.onGetEvents();
  }

  changeEventsView = (value) => {
    this.setState({ viewEvents: value });
  }

  render() {
    console.log(this.props);
    const { classes } = this.props;
    return (
        <div className={classes.root}>
          <EventCalendarView changeEventsView={this.changeEventsView}/>
          {
            this.state.viewEvents === 'table'
              ? <EventCalendarTable />
              : <div>test</div>
          }

        </div>
    );
  }
}

export default withStyles(styles)(EventCalendar);

EventPage/component.jsx

import React from 'react';
import EventCalendar from '../../components/EventCalendar';
import './index.scss';

function Events(props) {
  return (
    <React.Fragment>
      <EventCalendar props={props}/>
    </React.Fragment>
  );
}

export default Events;

EventPage/container.js

import { connect } from 'react-redux';
import EventsPage from './component';
import { getEvents } from '../../../store/modules/Events/operations';

const mapStateToProps = ({ Events }) => ({
  Events
});

const mapDispatchToProps = dispatch => ({
  onGetEvents: () => {
    console.log(123);

    dispatch(getEvents());
  }
});

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

Events/actions.js

import * as types from './types';

export const eventsFetch = value => ({
  type: types.FETCHING_EVENTS,
  payload: value
});

export const setEvents = ({ objById, arrayIds }) => ({
  type: types.SET_EVENTS,
  payload: {
    eventById: objById,
    eventsOrder: arrayIds
  }
});

Events/types.js

export const FETCHING_EVENTS = 'Events/FETCHING_EVENTS';
export const SET_EVENTS = 'Events/SET_EVENTS';

Events/operation.js

import FetchClient from 'app/utils/FetchClient';
import IdsAndByIds from 'app/utils/IdsAndByIds';
import { eventsFetch, setEvents } from './actions';

export const getEvents = () => async (dispatch) => {
  try {
    const { data } = await FetchClient.get('/events');
    dispatch(setEvents(IdsAndByIds(data)));
    dispatch(eventsFetch(false));
  } catch (error) {
    console.log(error);
  }
};

Events/reducer.js

import { createReducer } from 'store/utils';
import * as types from './types';

const usersInitState = {
  fetching: true,
  events: {
    eventById: null,
    usersOrder: null
  },
  error: null
};

const eventsReducer = createReducer(usersInitState)({
  [types.FETCHING_EVENTS]: (state, { payload }) => ({
    ...state,
    fetching: payload
  }),
  [types.SET_EVENTS]: (state, { payload }) => ({
    ...state,
    events: {
      ...payload
    }
  })
});

export default eventsReducer;

Events/index.js

import { combineReducers } from 'redux';
import * as eventsListOperations from './operations';
import reducer from './reducers';

const EventsReducer = combineReducers({
  eventsList: reducer
});

export default EventsReducer;
export { eventsListOperations };

Upvotes: 0

Views: 130

Answers (1)

Shubham Khatri
Shubham Khatri

Reputation: 281626

The issue here is a minor one, Since you are connecting Events component to connect, you are receiveing the prop onGetEvents in that component, Now inside this component you are passing the props by a name props to the EventCalendar component

 <EventCalendar props={props}/>

Now the props in EventCalender will contain a key called as props which wil lhave your data but you are trying to access it directly on props which is why it is undefined.

The correct way to pass the props here would be to use spread syntax like

 <EventCalendar {...props}/>

Upvotes: 3

Related Questions