Getting started with react-datepicker
Tags: react, javascript, tutorial
Published: 2020-09-02 21:15:03

Nobody likes working with dates (especially in Javascript) but we all have to. If your app requires a date picker component (think: select a date from a calendar), HackerOne has you covered with the [`react-datepicker` library](https://reactdatepicker.com/). This guide will walk through `react-datepicker` basics with a focus on building internal tools

By the end of this article, you’ll know how to:
* Import and use `react-datepicker` in your React app to build a simple datepicker
* Customize your datepicker with time functionality, disabling dates, and a clear button

## `react-datepicker` basics and setup
<br>

`react-datepicker` is a React library that is used by more than 40K developers with almost 5K stars on [GitHub](https://github.com/Hacker0x01/react-datepicker). The simple version of the datepicker component is incredibly easy to use and comes with some great features, including:

* Localization
* Accessibility
* Advanced customization
* Range support

The entire library comes out to 437kB (the small size partially thanks to using `date-fns` instead of `moment`) and runs on the latest versions of Chrome, Firefox, and IE10+.

In this tutorial, we’ll rum with an example use case: building an internal tool for a customer support team. Let’s say that we’ve already built a table that displays order data using `react-table`, and now we just need to add two datepickers so customer support reps can view orders between a range of dates.

Our datepicker needs to have the ability to:
* Open a calendar view when the datepicker is clicked
* Display selected range
* Display selectable times
* Disable future dates
* Clear the datepicker when the X button is clicked

And here's what the final product will look and feel like:

![Retool-Use-React-datepicker-Example-10-2](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-10-2.gif)

## Getting started
<br>

*If you're just here for the code, go ahead and <a href="#tldr">jump to the TL;DR syntax summary</a>.*

To start off, let’s keep things simple. We’ll create one datepicker without added customization, style, or features (literally all we’re doing is picking a date). 

We'll be using the `useState()` hook in our function. If you’re not familiar with React Hooks, we recommend checking out React’s [Hooks at a Glance](https://reactjs.org/docs/hooks-overview.html) docs before starting this tutorial.

There are three simple steps for creating a datepicker:

1. Import the datepicker component from `react-datepicker` and `react-datepicker.css` for styling.
2. Set an initial date in the state (using the `useState()` Hook).
3. Render the datepicker, telling `onChange` to update the date in state using the `setDate()` function.

```
import React, { useState } from "react";

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

export default function TableDatePicker() {
 const [date, setDate] = useState(new Date());

 return (
   <DatePicker selected={date} onChange={date => setDate(date)} />
 );
}
```

And, voila, you have a datepicker that starts on today’s date and will open a calendar to select a new date when clicked!

![Retool-Use-React-datepicker-Example-2](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-2.gif)

## Create a datepicker range
<br>

The first feature we are going to add is the ability to set a date range on our datepicker. We want our customer support reps to be able to narrow down orders that happened between a specific set of dates.

`react-datepicker` doesn’t have native support for ranges, but we can get around it by doubling the datepicker component: one for the start date and one for the end date. Now that we already have our first datepicker, we simply need to adjust it to specifically handle a start date:

```
export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());

 return (
   <DatePicker
     selected={startDate}
     onChange={date => setStartDate(date)}
     selectsStart // tells this DatePicker that it is part of a range*
     startDate={startDate}
   />
 );
}
```

Then, we'll create a second datepicker that can handle the end date. Note that the `endDate` datepicker needs a `minDate` to be set. Since we’re picking a range, we can’t have the `endDate` be earlier than the `startDate` (time doesn’t work like that!).

```
export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());
 const [endDate, setEndDate] = useState(new Date());

 return (
   <div> // don't forget to wrap your DatePickers
     <DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate} // add the endDate to your startDate DatePicker now that it is defined
       onChange={date => setStartDate(date)}
     />
    <DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date => setEndDate(date)}
     />
   </div>
 );
}
```

And that’s it! The final version of the code all put together will look like this:

```
import React, { useState } from "react";

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());
 const [endDate, setEndDate] = useState(new Date());

 return (
   <div>
     <DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date => setStartDate(date)}
     />
     <DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date => setEndDate(date)}
     />
   </div>
 );
}
```

Now we have two datepickers that the customer support reps can use to select their ranges. Plus, the `react-datepicker` library already handles highlighting the selected dates for us.

![Retool-Use-React-datepicker-Example-3](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-3.gif)

## Selecting times
<br> 
    
Let’s assume that our example company has thousands of rows of data, filled with row after row of customer order data. Even if reps only select a couple days, they’ll still get flooded with a ton of data. To make life easier for them, let’s add in time to the datepicker so that the range can get super granular.

`react-datepicker` comes with two options for adding time to the calendar view:

![Retool-Use-React-datepicker-Example-4](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-4.png)

While the input version can be very useful since it lets the user type in any time they want, we’re going to go with the select version because we’re okay with only letting our customer support reps choose times in half-hour increments. 

To add the time selector to our datepickers, we’ll first add `showTimeSelect` to our datepicker component to let it know we want to display the time selector, and then we’ll format the date that’s displayed in the datepicker window so that it shows time too.

```
<DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date => setStartDate(date)}
/>
<DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date => setEndDate(date)}
/>
```

Hey, that took almost no *time* at all (sorry).

![Retool-Use-React-datepicker-Example-5](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-5.gif)

## Extend your datepicker with more features
<br>

We've just barely scratched the surface of what `react-datepicker` can do. A few useful ones:

**→ Add a placeholder prompt to the datepicker**

Instead of having the datepicker start on today’s date, why don’t we prompt the user to enter a start and end date so that our range datepicker is a little more clear? To do this, we need to add a `placeholderText` field and change the initial startDate and endDate values to `null`.

```
export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(null);
 const [endDate, setEndDate] = useState(null);

 return (
   <div>
     <DatePicker
       placeholderText="Select Start Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date => setStartDate(date)}
     />
     <DatePicker
       placeholderText="Select End Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date => setEndDate(date)}
     />
   </div>
 )
}
```

![Retool-Use-React-datepicker-Example-6](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-6.gif)

**→ Disable future dates**

Since our reps are dealing with orders from customers, all of the data in the table they are viewing will be in the past. If they were to select a date in the future, there would be no data to view, and the rep would be looking at an empty table. Instead of that happening, lets disable all future dates in the calendar so that the rep can’t select them.

For this feature, we’re going to add the `filterDate` field and define an arrow function that returns a Boolean value depending on whether the date displayed is in the future or not.

```
<DatePicker
 filterDate={d => {
   return new Date() > d;
 }}
 placeholderText="Select Start Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date => setStartDate(date)}
/>
<DatePicker
 filterDate={d => {
   return new Date() > d;
 }}
 placeholderText="Select End Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={endDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date => setEndDate(date)}
/>
```

Great! Now the rep will only be able to filter the table based on dates that actually have order data.

![Retool-Use-React-datepicker-Example-7](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-7.gif)

**→ Add a clear button to the datepicker**

If the customer support rep decides that they no longer want to filter by date, we want to make that experience as easy as possible for them. Instead, let’s give them a simple `X` they can press to clear the datepicker.

```
<DatePicker
 isClearable
 filterDate={d => {
   return new Date() > d;
 }}
 placeholderText="Select Start Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date => setStartDate(date)}
/>
<DatePicker
 isClearable
 filterDate={d => {
   return new Date() > d;
 }} 
 placeholderText="Select End Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={endDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date => setEndDate(date)}
/>
```

This one is just a simple Boolean prop type that is passed in to datepicker. Here is what the default clear button looks like:

![Retool-Use-React-datepicker-Example-8](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-8.png)

At this point we should probably let you know that we added a little extra styling to make the datepicker look this way. If you choose to display the time in your datepicker, the clear button sits right on top of it, like this:

![Retool-Use-React-datepicker-Example-9](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-9.png)

In order to expand the width of the datepicker boxes, we have to override some of the styling that we imported in `react-datepicker.css`. To do this, we are going to use [Styled Components](https://styled-components.com/), a popular React library used for low-level styling.

First, import `styled-components`, and then define a new `Styles` component that will wrap around your datepicker. Then, move all of your datepicker code into a new function. You want your default function to export just your datepicker code (all wrapped up) with the `<Styles>` component around it.

Take careful note of the `react-datepicker` classnames that must be overwritten:
* `react-datepicker-wrapper`
* `react-datepicker__input-container` 
* `react-datepicker__input-container input` 

```
import React, { useState } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import styled from "styled-components";

const Styles = styled.div`
 .react-datepicker-wrapper,
 .react-datepicker__input-container,
 .react-datepicker__input-container input {
   width: 175px;
 }
`;

export function DatePickerRange() {
 const [startDate, setStartDate] = useState(null);
 const [endDate, setEndDate] = useState(null);

 return (
   <div>
     <DatePicker
       isClearable
       ...
     />
     <DatePicker
       isClearable
       ...
     />
   </div>
 );
}

export default function TableDatePicker() {
 return (
   <Styles>
     <DatePickerRange />
   </Styles>
 );
}
```

And now that we’re overwriting classnames from `react-datepicker`, we might as well change up the style of our clear button. To override the button styles, you just need to change `.react-datepicker__close-icon::before` and `.react-datepicker__close-icon::after`.

```
const Styles = styled.div`
 .react-datepicker-wrapper,
 .react-datepicker__input-container,
 .react-datepicker__input-container input {
   width: 175px;
 }

 .react-datepicker__close-icon::before,
 .react-datepicker__close-icon::after {
   background-color: red;
 }
`;
```

Here is our new, styled `X` button:

![Retool-Use-React-datepicker-Example-10](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-10.gif)

## Extracting data from the datepicker
<br> 

Extracting the selected date(s) from your datepicker will depend on how your code is set up. Maybe that’s obvious, but let me explain.

If I’m within the same component, getting the `startDate` and `endDate` are as simple as accessing the state.

```
<div>
 <div style={{ display: "flex" }}>
   <DatePicker ... />
   <DatePicker ... />
 </div>
 <div>Selected start date={startDate ? startDate.toString() : null}</div>
 <div>Selected end date={endDate ? endDate.toString() : null}</div>
</div>
```

Here you can see we are printing the selected date below the datepickers. Note that `startDate` and `endDate` are saved as Date objects so you must convert them to Strings with the `toString()` method before printing (or else your IDE will yell at you).

![Retool-Use-React-datepicker-Example-11](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-11.png)

If you are working with multiple components, then you will likely need to lift the state out of the datepicker components. That work goes a bit beyond the scope of this tutorial, but you can read up on how to do it in the [React docs](https://reactjs.org/docs/lifting-state-up.html).

## Your datepicker component with `react-datepicker`
<br> 

Here is our final datepicker:

![Retool-Use-React-datepicker-Example-10-1](https://retool.com/blog/content/images/2020/08/Retool-Use-React-datepicker-Example-10-1.gif)

Hopefully, this tutorial helped you understand how to create and customize a datepicker in React to suit your needs. We know we covered a lot of features here, so for good measure, here is the code for the datepicker we created, in its entirety:

```
import React, { useState } from "react";

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import styled from "styled-components";

const Styles = styled.div`
 .react-datepicker-wrapper,
 .react-datepicker__input-container,
 .react-datepicker__input-container input {
   width: 175px;
 }

 .react-datepicker__close-icon::before,
 .react-datepicker__close-icon::after {
   background-color: grey;
 }
`;

export function DatePickerRange() {
 const [startDate, setStartDate] = useState(null);
 const [endDate, setEndDate] = useState(null);

 return (
   <div style={{ display: "flex" }}>
     <DatePicker
       isClearable
       filterDate={d => {
         return new Date() > d;
       }}
       placeholderText="Select Start Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date => setStartDate(date)}
     />
     <DatePicker
       isClearable
       filterDate={d => {
         return new Date() > d;
       }}
       placeholderText="Select End Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date => setEndDate(date)}
     />
   </div>
 );
}

export default function TableDatePicker() {
 return (
   <Styles>
     <DatePickerRange />
   </Styles>
 );
}
```

For more code samples that cover the vast range of features that `react-datepicker` has to offer, check out [React Datepicker’s website](https://reactdatepicker.com/).

For a full version of this code that you can test out and play around with, check out our [code sandbox](https://codesandbox.io/s/react-datepicker-ig3u9).
         
<h2 id="tldr">TL;DR: Syntax roundup</h2>
<br>

### Create a simple datepicker
```
import React, { useState } from "react";

import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";

export default function TableDatePicker() {
 const [date, setDate] = useState(new Date());

 return (
   <DatePicker selected={date} onChange={date => setDate(date)} />
 );
}
```

### Create a datepicker range
```
export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());
 const [endDate, setEndDate] = useState(new Date());

 return (
   <div>
     <DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date => setStartDate(date)}
     />
     <DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date => setEndDate(date)}
     />
   </div>
 );
}
```

### Selecting time with datepicker
```
<DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={date}
 onChange={date => setDate(date)}
/>
```

### Add a placeholder
```
export default function TableDatePicker() {
 const [date, setDate] = useState(null);

 return (
   <DatePicker
     placeholderText="Select Date"
     selected={date}
     onChange={date => setDate(date)}
   />
 );
}
```
       
### Disable future dates
```
<DatePicker
 filterDate={d => {
   return new Date() > d;
 }}
 selected={date}
 onChange={date => setDate(date)}
/>
```
    
### Add a clear button to the datepicker
```
<DatePicker
 isClearable
 selected={date}
 onChange={date => setDate(date)}
/>
```