Search code examples
reactjsrenderweb-component

react willReceiveProps workaround for external library


I'm using a react datepicker component that can be found here. The component is pretty great except for what appears to be an oversight: it does not implement willReceiveProps.

To expound, I create the datpicker as below:

<DateField
  dateFormat= { dateFormat}
  forceValidDate={true}
  defaultValue={startDate || ''}
  onChange={this.handleChange.bind(null, 'start_date')}
  id="start"
>
  <DatePicker
    navigation={true}
    locale="en"
    forceValidDate={true}
    highlightWeekends={true}
    highlightToday={true}
    weekNumbers={true}
    weekStartDay={0}
  />
</DateField>

Note above that there is a prop defaultValue which I pass startDate. Now, startDate can and does change for reasons that are sometimes external to the component. That value is passed during a new render() action as per usual. According to react philosophy this shouldn't be a problem.

However, it appears to me as if the value from defaultValue is only ever read once inside DateField. It is read as this.props.defaultValue. Anyone who has ever built a component relying on props should quickly recognize this is a problem. It means that when the prop is changed the new value will not be used.

Because this is a library, I cannot simply implement willReceiveProps. Does anyone know of a good workaround to get this component to either completely reset on a render or some other strategy to deal with what seems to be a big design problem?


Solution

  • They follow the same standards as the <input> component. defaultValue is read only once but there is also value that can be set externally. There is no need for them to use willReceiveProps.

    In short, use value instead of defaultValue.

    See Uncontrolled Components in React

    PS: I am looking a bit into the code and it seems there are also properties text and date apart from value. Since the code (and documentation) has been removed from github, I won't inspect what is the difference between those props.