Hey, I'm trying to use react-dates for the first time, and I'm getting this error.
type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
Yes, I've included import react-dates/initialize at the top of my component.
Below is what I've got:
import 'react-dates/initialize';
// import 'react-dates/lib/css/_datepicker.css';
import React from 'react';
import _ from 'lodash';
import PropTypes from 'prop-types';
import moment from 'moment';
import DateRangePicker from 'react-dates';
import { getLastWeekDay } from '../utils/Helpers';
import { Button } from 'react-bootstrap';
class DateRangeInput extends React.Component {
constructor(props) {
super(props);
this.state = {
focused: null
};
}
onDatesChange = (startDate, endDate, label) => {
if (label !== undefined) {
alert('custom!');
}
this.props.onChange(startDate, endDate);
};
renderDatePresets = () => {
return _.forOwn(this.props.presets, ([start, end], label) => {
const isSelected = start.isSame(this.props.startDate) && end.isSame(this.props.endDate);
return (
<Button
onClick={() => this.onDatesChange(start, end, label)}
disabled={isSelected}
>
{label}
</Button>
)
});
};
render() {
const {startDate, endDate, onChange} = this.props;
return (
<div>
<DateRangePicker
renderCalendarInfo={this.renderDatePresets}
onDatesChange={this.onDatesChange}
startDate={startDate}
endDate={endDate}
startDateId="start_date_id"
endDateId="end_date_id"
focusedInput={this.state.focused}
onFocusChange={focused => this.setState({ focused })}
/>
</div>
);
}
}
DateRangeInput.propTypes = {
startDate: (props, propName) => moment.isMoment(propName),
endDate: (props, propName) => moment.isMoment(propName),
dateFormat: PropTypes.string.isRequired,
presets: PropTypes.shape({
[PropTypes.string]: PropTypes.arrayOf((propValue, key) => moment.isMoment(propValue[key]))
}).isRequired,
onChange: PropTypes.func.isRequired,
};
DateRangeInput.defaultProps = {
startDate: moment(),
endDate: moment(),
dateFormat: 'YYYYMMDD',
presets: {
'Today' : [moment(), moment()],
'Last week day': [getLastWeekDay(), getLastWeekDay()],
'Last 7 Days' : [moment().subtract(6, 'days'), moment()],
'Last 30 Days' : [moment().subtract(29, 'days'), moment()],
'This Month' : [moment().startOf('month'), moment()],
'Last Month' : [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
'This Year' : [moment().startOf('year'), moment()],
'Last Year' : [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')],
}
};
export default DateRangeInput;
After browsing some other related issues, I'm pulling my hair out.
By the way, do I even need to do import 'react-dates/lib/css/_datepicker.css? Babel complains about an invalid token in the CSS file.
What does _.forOwn return?
So it seems I misread the documentation in _.forOwn - I assumed that it acted as a map over the keys of an object, whereas it's more of a forEach. Either way, I had tested this code without passing a renderCalendarInfo prop and I was still getting the same issue. I've fixed renderDatePresets now, but I still get the same error with this updated code:
renderDatePresets = () => {
return Object.keys(this.props.presets).map(label => {
const [start, end] = this.props.presets[label];
const isSelected = start.isSame(this.props.startDate) && end.isSame(this.props.endDate);
return (
<Button
key={label}
onClick={() => this.onDatesChange(start, end, label)}
disabled={isSelected}
>
{label}
</Button>
);
});
};
render() {
const {startDate, endDate, onChange} = this.props;
console.log(this.renderDatePresets());
return (
<div>
<DateRangePicker
// renderCalendarInfo={this.renderDatePresets}
onDatesChange={this.onDatesChange}
startDate={startDate}
endDate={endDate}
startDateId="start_date_id"
endDateId="end_date_id"
focusedInput={this.state.focused}
onFocusChange={focused => this.setState({ focused })}
/>
</div>
);
}
renderDatePresets now returns an array of 8 buttons - but this is unrelated to the error.
Your import of DateRangePicker is wrong - react-dates doesn鈥檛 have a default exported component.
@ljharb thanks!
Prior to posting this question, I did play around with the import statement, and instead I was getting import errors - I then assumed that the default-export method of importing was the correct thing to do, as I wasn't getting any import errors, merely that cryptic error message, so I didn't think the import was an issue.
It appears that changing the import to { DateRangePicker } and then adding the line 'node_modules/react-dates/index.js': ['DateRangePicker'] to the namedExports section of the commonjs plugin configuration in rollup.config.js has resolved this issue.
I also solved the issue with including the css file by adding the path node_modules/react-dates/lib/css/*.css to the include section of the postcss plugin in my rollup.config.js.
It might be worth documenting the above measures needed to make this work with rollup.
If rollup requires additional measures to work with standard npm ecosystem patterns, then that's something rollup needs to document, not "every single package on npm".
However, it'd be great to clear up the react-dates docs on the CSS file, since that's not a conventional practice like named imports. A PR is welcome!
Most helpful comment
@ljharb thanks!
Prior to posting this question, I did play around with the import statement, and instead I was getting import errors - I then assumed that the default-export method of importing was the correct thing to do, as I wasn't getting any import errors, merely that cryptic error message, so I didn't think the import was an issue.
It appears that changing the import to
{ DateRangePicker }and then adding the line'node_modules/react-dates/index.js': ['DateRangePicker']to thenamedExportssection of thecommonjsplugin configuration inrollup.config.jshas resolved this issue.I also solved the issue with including the css file by adding the path
node_modules/react-dates/lib/css/*.cssto theincludesection of thepostcssplugin in myrollup.config.js.It might be worth documenting the above measures needed to make this work with
rollup.