0

I'm learning React and Redux. I got stuck with a connection of the react-dates component to the Redux. The main problem is that something (possibly react-dates) fires redux actions (SET_START_DATE, SET_END_DATE) at the start of an app, even though they should happen after I click on a date inside of a calendar. Thus I'm getting these errors:

Failed prop type: Invalid input type: `startDate` of type `string` 
supplied to `withStyles(DateRangePicker)`, expected `object`.

Failed prop type: Invalid input type: `endDate` of type `string` 
supplied to `withStyles(DateRangePicker)`, expected `object`.

Uncaught TypeError: date.format is not a function

Component's code with DatePicker:

import 'react-dates/initialize';
import 'react-dates/lib/css/_datepicker.css';

import React, {Component} from 'react';
import {connect} from 'react-redux';

import {DateRangePicker} from 'react-dates'
import {setEndDate, setStartDate} from "../actions/filters";

class Filters extends Component {

state = {
    calendarFocused: null
};

onDatesChange = ({startDate, endDate}) => {
    this.props.setStartDate(startDate);
    this.props.setEndDate(endDate);
};

onFocusChange = (calendarFocused) => {
    this.setState(() => ({calendarFocused}));
};

render() {
    return (
        <div>

            {
                <DateRangePicker
                    startDateId="startDate"
                    endDateId="endDate"
                    startDate={this.props.startDate}
                    endDate={this.props.endDate}
                    onDatesChange={this.onDatesChange}
                    focusedInput={this.state.calendarFocused}
                    onFocusChange={this.onFocusChange}
                    showClearDates={true}
                    numberOfMonths={1}
                    isOutsideRange={() => false}
                />
            }

        </div>
    );
   }
}

function mapStateToProps(state) {
   return {
       startDate: state.filters.startDate,
       endDate: state.filters.endDate
   };
  }

function mapDispatchToProps(dispatch) {
   return {
       setStartDate: (startDate) => dispatch(setStartDate(startDate)),
       setEndDate: (endDate) => dispatch(setEndDate(endDate)),
   };
}

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

Actions:

// SET_START_DATE
export const setStartDate = (startDate) => ({
    type: 'SET_START_DATE',
    startDate
});

// SET_END_DATE
export const setEndDate = (endDate) => ({
    type: 'SET_END_DATE',
    endDate
});

Reducers:

import moment from 'moment';

const filtersReducerDefaultState = {
    startDate: moment().startOf('month'),
    endDate: moment().endOf('month')
};

export default (state = filtersReducerDefaultState, action) => {
    switch (action.type) {

        case 'SET_START_DATE': {

            console.log(action.startDate);

            return {
                ...state,
                startDate: action.startDate
            }
        }

        case 'SET_END_DATE': {
            return {
                ...state,
                endDate: action.endDate
            }
        }

        default:
            return state;

    }
};

I'm using these dependencies:

  • "react": "^16.4.2",
  • "react-dates": "^17.2.0",
  • "react-redux": "^5.0.7",
  • "redux": "^4.0.0",
  • "redux-thunk": "^2.3.0"
Hyyan Abo Fakher
  • 3,497
  • 3
  • 21
  • 35
tawreon
  • 184
  • 12
  • It is hard to tell from this what could be firing those actions on application init. However could you not simply use a guard if statement to keep your state from being updated in your reducer unless it is a date object? – tnyN Sep 05 '18 at 12:28
  • 1
    @tnyN, This advice worked for me, I wrote type checking inside of a reducer, and the app doesn't throw errors so far. `case 'SET_START_DATE': { if (_.isObject(action.startDate)) { return { ...state, startDate: action.startDate } } else { return state; } }` However these actions are still firing unpredictably. – tawreon Sep 05 '18 at 12:42

0 Answers0