React-dates: Can I have two SDP(Single Date Pickers) in the same component?

Created on 27 Jan 2018  路  10Comments  路  Source: airbnb/react-dates

I want to use an individual date picker for the start date and the second for an end date

This is my code, as you can see I'm using the same code as in the docs, I think the issue is with the state because they have the same twice.

<SingleDatePicker
  date={this.state.date} // momentPropTypes.momentObj or null
  onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
  focused={this.state.focused} // PropTypes.bool
  onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
/>

<SingleDatePicker
  date={this.state.date} // momentPropTypes.momentObj or null
  onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
  focused={this.state.focused} // PropTypes.bool
  onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
/>

Most helpful comment

Hi @AndreaMorone , for me this solution was very good and fixed my problem.
Here is my code.

                 <SingleDatePicker
                      placeholder="Salida"
                      numberOfMonths={1}
                      displayFormat="DD MMM YYYY"
                      date={this.state.dateStart}
                      onDateChange={dateStart => this.setState({ dateStart })}
                      focused={this.state.focused}
                      onFocusChange={({ focused }) => this.setState({ focused })}
                      id="departure"
                   />
                   <SingleDatePicker
                      numberOfMonths={1}
                      displayFormat="DD MMM YYYY"
                      placeholder="Regreso"
                      date={this.state.dateEnd} // momentPropTypes.momentObj or null
                      onDateChange={dateEnd => this.setState({ dateEnd })}
                      focused={this.state.focusedDateEnd} // PropTypes.bool
                      onFocusChange={({ focused: focusedDateEnd}) => this.setState({ focusedDateEnd })}
                      id="back" // PropTypes.string.isRequired,
                   />

All 10 comments

Are you storing both dates and focuseds in your outer component's state under the same name?

Yes @ljharb , here is the full code of my component, I just got started working with React so maybe the issue is quite obvious but I can麓t see it. Both datepickers are not working at this point.

import React from "react";
import moment from "moment";
import 'react-dates/initialize';
import { DateRangePicker, SingleDatePicker, DayPickerRangeController } from 'react-dates';
import 'react-dates/lib/css/_datepicker.css';

moment.locale('es');

class NewEvent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      today: moment().format('DD'+'/'+'MM'+'/'+'YYYY'),
      date: null,
    };
  }

  render() {

    return(
      <form>
        <SingleDatePicker
          id="first"
          date={this.state.date} // momentPropTypes.momentObj or null
          onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
          focused={this.state.focused} // PropTypes.bool
          onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
          enableOutsideDays={false}
          displayFormat="DD/MM/YYYY"
          placeholder={this.state.today}
        />
        <SingleDatePicker
          id="second"
          date={this.state.date} // momentPropTypes.momentObj or null
          onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
          focused={this.state.focused} // PropTypes.bool
          onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
          enableOutsideDays={false}
          displayFormat="DD/MM/YYYY"
          placeholder={this.state.today}
        />
      </form>
    )
  }
}

export default NewEvent;

Right. so, you'll have to rename one of the components' state values, otherwise they conflict with each other.

Like this the first SDP works but the second doesn麓t.

Is this what you meant by changing the state?

class NewEvent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      date: null,
      dateTwo: null,
      focusedTwo: false,
    };
  }

  render() {

    return(
      <form>
        <SingleDatePicker
          id="first"
          date={this.state.date} // momentPropTypes.momentObj or null
          onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
          focused={this.state.focused} // PropTypes.bool
          onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
        />
        <SingleDatePicker
          id="second"
          date={this.state.dateTwo} // momentPropTypes.momentObj or null
          onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
          focused={this.state.focusedTwo} // PropTypes.bool
          onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
        />
      </form>
    )
  }
}

export default NewEvent;

onFocusChange={({ focused }) => this.setState({ focused })} is setting a state called "focused" twice, and onDateChange={date => this.setState({ date })} is setting a state called "date" twice. At least one of those pairs needs to be renamed.

Thanks for all the feedback @ljharb, so now both SDPs work but the second one is always showing up because I set the state to focusedTwo: true. I need to handle the focus right.

I think I'm not passing something right because onFocusChange needs a PropTypes.func.isRequired and I don't know what's that.

class NewEvent extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      date: null,
      dateTwo: null,
      focusedTwo: true
    };
  }

  render() {

    return(
      <form>
        <SingleDatePicker
          date={this.state.date} // momentPropTypes.momentObj or null
          onDateChange={date => this.setState({ date })} // PropTypes.func.isRequired
          focused={this.state.focused} // PropTypes.bool
          onFocusChange={({ focused }) => this.setState({ focused })} // PropTypes.func.isRequired
        />
        <SingleDatePicker
          date={this.state.dateTwo} // momentPropTypes.momentObj or null
          onDateChange={dateTwo => this.setState({ dateTwo })} // PropTypes.func.isRequired
          focused={this.state.focusedTwo} // PropTypes.bool
          onFocusChange={({ focus }) => this.setState({ focus })} // PropTypes.func.isRequired
        />
      </form>
    )
  }
}

Your first example consistently uses pairs of "focused" and "date".

Your second example uses a pair of "dateTwo", but then uses "focusedTwo" and "focus".

Your first example consistently uses pairs of "focused" and "date".

Your second example uses a pair of "dateTwo", but then uses "focusedTwo" and "focus".

This Doesn't work for me. What is the issue?

 constructor(props) {
        super(props);

        this.state = {
            fields: {},
            errors: {},
            date: '',
            date1: '',
            startDate: moment(),
            minDate: '1900/1/1',
            maxDate:moment(),
            endDate: moment(),
            dateRangeFocusedInput: true,
            focusedTwo: true,
            defaultSwitch: false,
            plainSwitch: false,
            iconSwitch: true,
            status: 'Active',
            statusClass:'text-primary'
        }
    }


                                        <SingleDatePicker
                                            date={date}
                                            onDateChange={date => this.setState({ date })}
                                            focused={this.state.focused}
                                            onFocusChange={({ focused }) => this.setState({ focused })}
                                            isOutsideRange={date => date.isBefore(minDate) || date.isAfter(maxDate)}

                                        />

                                          <SingleDatePicker
                                            date={date1}
                                            onDateChange={date1 => this.setState({ date1 })}
                                            focused={this.state.focusedTwo}
                                            onFocusChange={({ focusedTwo }) => this.setState({ focusedTwo })}
                                        />

Hi,
you should do:
onFocusChange={({ focused: focusedTwo }) => this.setState({ focusedTwo })}
because the onFocusChange callback passed back an object with a focused key, not a focusedTwo key.

Hi @AndreaMorone , for me this solution was very good and fixed my problem.
Here is my code.

                 <SingleDatePicker
                      placeholder="Salida"
                      numberOfMonths={1}
                      displayFormat="DD MMM YYYY"
                      date={this.state.dateStart}
                      onDateChange={dateStart => this.setState({ dateStart })}
                      focused={this.state.focused}
                      onFocusChange={({ focused }) => this.setState({ focused })}
                      id="departure"
                   />
                   <SingleDatePicker
                      numberOfMonths={1}
                      displayFormat="DD MMM YYYY"
                      placeholder="Regreso"
                      date={this.state.dateEnd} // momentPropTypes.momentObj or null
                      onDateChange={dateEnd => this.setState({ dateEnd })}
                      focused={this.state.focusedDateEnd} // PropTypes.bool
                      onFocusChange={({ focused: focusedDateEnd}) => this.setState({ focusedDateEnd })}
                      id="back" // PropTypes.string.isRequired,
                   />
Was this page helpful?
0 / 5 - 0 ratings

Related issues

easwee picture easwee  路  55Comments

comron picture comron  路  22Comments

wub picture wub  路  20Comments

aaronjensen picture aaronjensen  路  52Comments

nkint picture nkint  路  21Comments