redux-form-material-ui: DatePicker: Invalid prop value of type string

This is how I’m using the DatePicker component: <Field name="date" component={DatePicker} hintText="Pick a Date" />

Getting this error:

Failed prop type: Invalid prop `value` of type `string` supplied to `DatePicker`, expected `object`.
    in DatePicker (created by ReduxFormMaterialUIDatePicker)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 27
  • Comments: 28 (1 by maintainers)

Commits related to this issue

Most upvoted comments

@rafaelhz solution works for me. And it makes sense as the Datepicker component need value as an object. Please see my renderDatePicker function:

const renderDatePicker = ({ input, defaultValue, meta: { touched, error } }) => (
    <DatePicker 
        errorText = {touched && error} 
        {...input}
        value = {input.value !== ''? new Date(input.value) : null}
        onChange = {(event, value) => {console.log(value); input.onChange(value)}} />
)

And insert DatePicker in a Field component

<Field name="checkin_date" component={renderDatePicker} hintText="Checkin Date" autoOk={true} />

@Philipp91 Thanks!

How I fix it:

  1. import DatePicker from redux-form-material-ui, not from Material-ui
  2. Field component={DatePicker} format={(value, name) => value === ‘’ ? null : value}

Good luck!

the warning is related to the value property, not the defaultValue. The ReduxFormMaterialUIDatePicker is setting an empty string when the initial value of the Redux Form is not defined, the value should be an object.

I fixed it including a verification in the ReduxFormMaterialUIDatePicker: value: inputProps.value !== ‘’ ? inputProps.value : null

export default createComponent(
  DatePicker,
  ({
    input: {
      onBlur, // eslint-disable-line no-unused-vars
      onChange,
      ...inputProps
    },
    ...props
  }) => ({
    ...inputProps,
    ...mapError(props),
    onChange: (event, value) => onChange(value),
    value: inputProps.value !== '' ? inputProps.value : null
  })
)

You can now pass a format={null} to ensure that your Date value is not converted to a string.

@tchri You are probably still importing DatePicker from redux-form-material-ui where you should be importing it from material-ui/DatePicker for this fix to work.

@ducminhn no longer Invalid prop value of type string with this solution, but “Uncaught TypeError: Cannot read property ‘onBlur’ of undefined”.

I am getting this warning too and making thedefaultValue={null} doesn’t resolve things for me. I assume the material-ui example is now generating these warnings too?

With values restored from localStorage I did faced the issue that it could whether be a String or a date:

<Field
  name="date"
  component={DatePicker}
  format={(value, name) => value === '' ? null : (typeof value === 'string') ? new Date(value) : value}
/>

@restmount, @cif Thanks!


restmount comment

import DatePicker from redux-form-material-ui, not from Material-ui
Field component={DatePicker} format={(value, name) => value === '' ? null : value}

cif comment

<Field 
    name="expiresOn" 
    component={DatePicker} 
    format={(value, name) => { 
    console.log('value being passed:', value);
    console.log('is of type:', typeof value);
    return value === '' ? null : value 
}} />

so i edit my component like this.

import {  DatePicker } from 'redux-form-material-ui`;
<Field
    name="planDetails.startDate"
    component={DatePicker}
    container="inline"
    autoOk={true}
    format={(value) => value === '' ? null : new Date(value)}
    floatingLabelText="Plan Start" 
    hintText="Plan Start"/>

@megkadams the DatePicker is expecting a javascript Date object as the prop. To see what you are passing it, do this:

<Field 
  name="expiresOn" 
  component={DatePicker} 
  format={(value, name) => { 
    console.log('value being passed:', value);
    console.log('is of type:', typeof value);
    return value === '' ? null : value 
}} />

You will then need to use the value being passed to construct a new Date instance (or null), in my example I’m using new Date(isoStringFmt) for this purpose

I ended up doing this to solve my date issues: format={value => value ? new Date(value) : null} I am using Firebase as a back end so I end up having to convert to and from string anyway. Would be nice to update the component in this lib to check types

any news on this?

Yea, that doesn’t fix it. Should be a simple fix though…

I know this is an old one but what worked for me was setting propTypes like this:

DatePicker.propTypes = {
  date: PropTypes.instanceOf(Date).isRequired,
};

https://github.com/erikras/redux-form/blob/master/src/createFieldProps.js#L53 This is where the empty string comes from. Here’s the change, which also adjusted the documentation: https://github.com/erikras/redux-form/commit/345f46905c4e1bf38b5615b84cb58d507412f323

Providing initialValues is certainly not an option here. In my case, the error occurs before the proper initialValues are available.

To me, filtering out the special value “” and replacing it back with null seems legitimate (i.e. @rafaelhz solution). Though I’m not sure about @erikras reason he put in the Field documentation: Would that make the DatePicker an uncontrolled component? That’s certainly not desirable, but what else would you pass to a DatePicker to make it controlled, but empty? // EDIT: null doesn’t seem to make the component uncontrolled: https://github.com/callemall/material-ui/blob/master/src/DatePicker/DatePicker.js#L234

Another possibility could be to use the “format” parameter (https://github.com/erikras/redux-form/blob/master/src/createFieldProps.js#L67), though that would prevent the user from setting their own function there.

That’s because the Material UI TimePicker and DatePicker components now uses a Date object.

redux-form seems to convert any Date object passed as an initial value to a string, and the same goes for null.

One way around it would be


const mapError = ({ meta: { touched, error } = {}, input: { ...inputProps }, ...props }, errorProp = 'errorText') =>
  touched && error ? { ...props, ...inputProps, [errorProp]: error } : { ...inputProps, ...props }

function createComponent(MaterialUIComponent, mapProps) {
  class InputComponent extends Component {
    getRenderedComponent() {
      return this.refs.component;
    }

    render() {
      return createElement(MaterialUIComponent, {
        ...mapProps(this.props),
        ref: 'component',
      });
    }
  }
  InputComponent.displayName = `${MaterialUIComponent.name}`;
  return InputComponent;
}

export default createComponent(TimePicker,
  ({
    input: {
      onBlur,
      onChange,
      value,
      ...inputProps,
    },
    ...props,
  }) => {
    return {
      ...inputProps,
      ...mapError(props),
      value: value && new Date(value) || null,  // THIS IS THE WORKAROUND, we convert back to Date object
      onChange: (event, _value) => onChange(_value),
    };
  }
);

Not sure though if this should be added to the codebase, the issue seems deeper than that but I have not dug into redux-form really, maybe there is a reason for that conversion to an empty string. @erikras any input on this?