<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: justin gage</title>
    <description>The latest articles on DEV Community by justin gage (@itunpredictable).</description>
    <link>https://dev.to/itunpredictable</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F343417%2F099fc278-d22e-4c1a-9bc3-229a3fb5bfb9.jpg</url>
      <title>DEV Community: justin gage</title>
      <link>https://dev.to/itunpredictable</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itunpredictable"/>
    <language>en</language>
    <item>
      <title>CRUD with Firestore using the Node.js SDK</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Mon, 21 Sep 2020 14:07:13 +0000</pubDate>
      <link>https://dev.to/retool/crud-with-firestore-using-the-node-js-sdk-anp</link>
      <guid>https://dev.to/retool/crud-with-firestore-using-the-node-js-sdk-anp</guid>
      <description>&lt;p&gt;Cloud Firestore is great for building internal apps because it handles all the complicated ins and outs of managing a database for you. In this tutorial, we’ll show you how to set up a basic CRUD app with the Cloud Firestore using the Node.js SDK:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up the Cloud Firestore Node.js SDK&lt;/li&gt;
&lt;li&gt;&lt;a&gt;Create data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Read data&lt;/li&gt;
&lt;li&gt;Update data&lt;/li&gt;
&lt;li&gt;
Delete data &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up the Node.js SDK for Cloud Firestore
&lt;/h2&gt;



&lt;p&gt;To get started, you’ll first need install the Node.js client library and initialize your instance of the database. You can install the library via &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install firebase-admin --save 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the package is installed, you need to &lt;a href="https://firebase.google.com/docs/firestore/quickstart#initialize" rel="noopener noreferrer"&gt;initialize the database&lt;/a&gt;. You can do this with &lt;a href="https://firebase.google.com/products/functions" rel="noopener noreferrer"&gt;Firebase Cloud Functions&lt;/a&gt;, the Google Cloud Platform, or through your own server. For this tutorial, we’re going to quickly show you how to initialize the database on your own server using a &lt;a href="https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances" rel="noopener noreferrer"&gt;service account&lt;/a&gt;, which is an account identity used to make API requests to an application (learn more about service accounts &lt;a href="https://cloud.google.com/compute/docs/access/service-accounts#serviceaccount" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;First, you’ll need to go to the Service Accounts menu in Google Cloud Platform account (it’s under &lt;a href="https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?pli=1&amp;amp;supportedpurview=project" rel="noopener noreferrer"&gt;IAM &amp;amp; Admin&lt;/a&gt;). From there, generate a new private key, save it as a JSON file, and add it to your server.&lt;/p&gt;

&lt;p&gt;Then, in your &lt;code&gt;index.js&lt;/code&gt; file, include the &lt;code&gt;firebase-admin&lt;/code&gt; library and import your service account private key from your server. Use the &lt;code&gt;firebase-admin&lt;/code&gt; library to initialize your application, passing an object with &lt;code&gt;credential&lt;/code&gt; as the key and &lt;code&gt;firestore.credential.cert()&lt;/code&gt; (with your service account as an argument) as the value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require('firebase-admin');

const serviceAccount = require('./path/to/key.json');

fs.initializeApp({
 credential: fs.credential.cert(serviceAccount)
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, call the &lt;code&gt;firestore()&lt;/code&gt; amethod to create your database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const db = fs.firestore(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic CRUD with the Firestore Node.js SDK
&lt;/h2&gt;



&lt;p&gt;This wouldn’t be a CRUD tutorial without some sample data, so let’s get that out of the way. Imagine we’re building internal tools for an online retailer — let’s say a tool to show customer support reps some user data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "first": "Liam",
 "last": "Ragozzine",
 "address": "133 5th St., San Francisco, CA",
 "birthday": "05/13/1990",
 "age": "30"
},
{
 "first": "Vanessa",
 "last": "Peluso",
 "address": "49 Main St., Tampa, FL",
 "birthday": "11/30/1977",
 "age": "47"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This dataset is, of course, overly simplified - for more complex setups, there are a couple of options for structuring your data in Firestore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documents&lt;/li&gt;
&lt;li&gt;Multiple collections&lt;/li&gt;
&lt;li&gt;Subcollections within documents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one has pros and cons that play into ease of use, scalability, and complexity. You can read more about structuring data in Cloud Firestore right &lt;a href="https://firebase.google.com/docs/firestore/manage-data/structure-data" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Got it? Great! Now for CRUD.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating data with &lt;code&gt;set()&lt;/code&gt;
&lt;/h3&gt;



&lt;p&gt;To fill our database, we’re going to use the &lt;a href="https://firebase.google.com/docs/firestore/manage-data/add-data#set_a_document" rel="noopener noreferrer"&gt;&lt;code&gt;set()&lt;/code&gt; method&lt;/a&gt;. First, we’re going to specify that we want to fill the &lt;code&gt;users&lt;/code&gt; collection with the &lt;code&gt;collection()&lt;/code&gt; method. To do this, simply pass the name of the collection into the method as a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const usersDb = db.collection('users'); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to specify the first document so we can add our new user, Liam Ragozzine. To do this, we’ll use the &lt;a href="https://firebase.google.com/docs/firestore/manage-data/add-data#add_a_document" rel="noopener noreferrer"&gt;&lt;code&gt;doc()&lt;/code&gt; method&lt;/a&gt;. To use this method, pass the &lt;code&gt;id&lt;/code&gt; of the document into &lt;code&gt;doc()&lt;/code&gt; as a string. For this example, the &lt;code&gt;id&lt;/code&gt; is ‘lragozzine’.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liam = usersDb.doc('lragozzine'); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After specifying the document we want to add, we can set the data for the document by passing the data as an object into &lt;code&gt;set()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await liam.set({
 first: 'Liam',
 last: 'Ragozzine',
 address: '133 5th St., San Francisco, CA',
 birthday: '05/13/1990',
 age: '30'
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! Now, if we wanted to add our second user, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await usersDb.doc('vpeluso').set({
 first: 'Vanessa',
 last: 'Peluso',
 address: '49 Main St., Tampa, FL',
 birthday: '11/30/1977',
 age: '47'
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One important thing to note: the &lt;code&gt;set()&lt;/code&gt; method will overwrite a document if it already exists. We’ve been using &lt;code&gt;.doc(ID)&lt;/code&gt; to create new documents via &lt;code&gt;set()&lt;/code&gt;, but if a document with the passed ID already exists, the data you pass in &lt;code&gt;.set()&lt;/code&gt; will override whatever currently exists. &lt;/p&gt;

&lt;p&gt;Now that we’ve got data in our database, we can move on to reading it.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading data with &lt;code&gt;get()&lt;/code&gt;
&lt;/h3&gt;



&lt;p&gt;To read your data from Firestore, use the &lt;a href="https://firebase.google.com/docs/firestore/query-data/get-data#get_a_document" rel="noopener noreferrer"&gt;&lt;code&gt;get()&lt;/code&gt; method&lt;/a&gt;. To read from a collection, specify a &lt;code&gt;collection()&lt;/code&gt; before calling &lt;code&gt;get()&lt;/code&gt;. Or, if you need to read from a document, specify a &lt;code&gt;doc()&lt;/code&gt; before calling &lt;code&gt;get()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// get collection
const users = await db.collection('users').get();

// get document
const liam = await db.collection('users').doc('liam').get();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the document doesn’t exist, the result will be empty. So in the above example, &lt;code&gt;liam&lt;/code&gt; would have no data. You can check this by calling exists on the doc. If the document &lt;code&gt;exists&lt;/code&gt;, it will return true and you can call &lt;code&gt;data()&lt;/code&gt; to read the data of the document. Otherwise, it will return false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (!liam.exists) {
 console.log('No document');
} else {
 console.log(liam.data());
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To filter (“query”) your results, you can use &lt;code&gt;where()&lt;/code&gt;, which takes three arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A field from the collection to test the value of&lt;/li&gt;
&lt;li&gt;Relational operator (like &amp;lt;, &amp;gt;, or == for example)&lt;/li&gt;
&lt;li&gt;The value for the first argument to be evaluated against&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, if we wanted all documents for users who are younger than 40, we’d use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const under30 = await
 db.collection('users').where('age', '&amp;lt;=', 40).get();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What’s really cool about Cloud Firestore is that you can get real-time updates on your data using the &lt;a href="https://firebase.google.com/docs/firestore/query-data/listen" rel="noopener noreferrer"&gt;&lt;code&gt;onSnapshot()&lt;/code&gt; method&lt;/a&gt;. This lets you listen for changes to any of the documents in your database. After initializing the method and passing a callback function to handle the data, you’ll receive an update every time there’s a change to the content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liam = db.collection('users').doc('liam');

const observer = liam.onSnapshot(snapshot =&amp;gt; {
 console.log(`changes: ${snapshot}`);
}, err =&amp;gt; {
 console.log(`Error: ${err}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your app is current with the latest trends. 😎&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating data with &lt;code&gt;set()&lt;/code&gt; and &lt;code&gt;update()&lt;/code&gt;
&lt;/h3&gt;



&lt;p&gt;In Firestore there are two ways to update data: &lt;code&gt;set()&lt;/code&gt; or &lt;code&gt;update()&lt;/code&gt;. In short, using &lt;code&gt;set()&lt;/code&gt; will generally overwrite the entire document you’re working with, while &lt;code&gt;update()&lt;/code&gt; is best for updating particular fields while leaving others untouched.&lt;/p&gt;

&lt;p&gt;Starting with &lt;code&gt;set()&lt;/code&gt;, if we wanted to make a note in Liam’s document that he is married, we would call &lt;code&gt;set()&lt;/code&gt; with the object &lt;code&gt;{ married: true }&lt;/code&gt;. Like we mentioned above, it’s important to note that if you use set() on a document that already exists, you’ll overwrite it unless you specify &lt;code&gt;merge: true&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liam = await
 db.collection('users').doc('lragozzine').set({
   married: true
 }, { merge: true });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Hint: If you’re not sure whether a document already exists, add &lt;code&gt;merge&lt;/code&gt; just in case, so you don’t overwrite your data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To use the &lt;a href="https://firebase.google.com/docs/firestore/manage-data/add-data#update-data" rel="noopener noreferrer"&gt;&lt;code&gt;update()&lt;/code&gt; method&lt;/a&gt; to update a field in a document, pass an object with the field you wish to update as an argument to &lt;code&gt;update()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liam = await
 db.collection('users').doc('lragozzine').update({
   married: true
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To update data in a nested object, you’ll also want to use &lt;code&gt;update()&lt;/code&gt;. If we wanted to add an object that contained key-value pairs about a customer’s favorite things (like favorite color, product line, or bad ’90s TV show), we would pass an object where the key is a path, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liam = await
 db.collection('users').doc('lragozzine').update({
   'favorites.item': 'Ties'
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we know how to merge and update our documents, let’s move on to deleting.&lt;/p&gt;



&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deleting data with &lt;code&gt;delete()&lt;/code&gt;
&lt;/h3&gt;



&lt;p&gt;This shouldn’t be a surprise: you delete data from Firestore using the &lt;a href="https://firebase.google.com/docs/firestore/manage-data/delete-data#delete_documents" rel="noopener noreferrer"&gt;&lt;code&gt;delete()&lt;/code&gt; method&lt;/a&gt;. It’ll look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await db.collection('users').doc('lragozzine').delete(); 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will delete Liam’s entire document from the &lt;code&gt;users&lt;/code&gt; database.&lt;/p&gt;

&lt;p&gt;Note: If you delete a document, it will not delete the document’s subcollections. So if Liam had a subcollection in his document that contained documents with order data, called &lt;code&gt;orders&lt;/code&gt;, then even after deleting the &lt;code&gt;lragozzine&lt;/code&gt; document, we would still be able to access the subcollection &lt;code&gt;orders&lt;/code&gt;, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const liamOrders = await db.collection('users').doc('lragozzine')
 .collection('orders').doc('123').get();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To &lt;a href="https://firebase.google.com/docs/firestore/manage-data/delete-data#fields" rel="noopener noreferrer"&gt;delete a field&lt;/a&gt;, use &lt;code&gt;FieldValue.delete()&lt;/code&gt; in an &lt;code&gt;update()&lt;/code&gt; command. First, you must import the &lt;code&gt;FieldValue&lt;/code&gt; object, and then call &lt;code&gt;delete()&lt;/code&gt; on it, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const FieldValue = fs.firestore.FieldValue;

const r = await
 db.collection('users').doc('lragozzine').update({
   married: FieldValue.delete();
 });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deleting entire collections gets a little more complicated because you have to make requests to retrieve all documents in a collection and delete them one by one. For more information on deleting collections, check out &lt;a href="https://firebase.google.com/docs/firestore/solutions/delete-collections" rel="noopener noreferrer"&gt;Firebase’s guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations! You’re now a Cloud Firestore CRUD expert.&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>firestore</category>
      <category>webdev</category>
      <category>node</category>
    </item>
    <item>
      <title>How to Build a React Form Component</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Tue, 15 Sep 2020 17:16:53 +0000</pubDate>
      <link>https://dev.to/retool/how-to-build-a-react-form-component-3jg8</link>
      <guid>https://dev.to/retool/how-to-build-a-react-form-component-3jg8</guid>
      <description>&lt;p&gt;Whether it's a login page or an internal tool, your React app is going to need a form, and handling events and dataflow via raw HTML inputs isn't any fun. This guide will walk you through how to use the &lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;&lt;code&gt;react-hook-form&lt;/code&gt; library&lt;/a&gt; and take you step-by-step through a project where we create a form for an internal tool and extend it with some useful features.&lt;/p&gt;

&lt;p&gt;By the end of this article, you’ll know how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a simple form using &lt;code&gt;react-hook-form&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Style your form&lt;/li&gt;
&lt;li&gt;Validate your form&lt;/li&gt;
&lt;li&gt;Add errors to your form&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started / basics
&lt;/h2&gt;



&lt;p&gt;&lt;em&gt;If you’re just here to snag some code, we got you.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial, we're working with a table that lists and orders our data, and has a nifty datepicker for sifting through the orders.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-table-example_Retool.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-table-example_Retool.png" alt="React-form-table-example_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, while we know most folks place orders online, we have to recognize that sometimes customers like to order over the phone. This means that we need to give our reps the ability to add new orders to the table.&lt;/p&gt;

&lt;p&gt;Our React form component needs to be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accept a customer’s name, address, the date the order was made, and an order number&lt;/li&gt;
&lt;li&gt;Validate the data that the customer support rep enters&lt;/li&gt;
&lt;li&gt;Display errors to the rep&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is what the final product will look and feel like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Table-Final_Retool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Table-Final_Retool.gif" alt="React-Form-Table-Final_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First things first, &lt;code&gt;react-hook-form&lt;/code&gt; is a library built to handle the data in forms and do all the complicated work with validation, error handling, and submitting. There are no physical components in the library. The form component that we will build will just be made with standard &lt;code&gt;jsx&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;To start off, we’re going to build a simple form with no styling - it’s going to be a bunch of &lt;code&gt;textarea&lt;/code&gt; inputs for the reps to fill out the customer’s name, address, the date of the order, and the order number, and, finally, a plain “submit” button. Keep in mind that &lt;code&gt;react-hook-form&lt;/code&gt; uses React Hooks. Hooks are a fairly new feature to React, so if you aren’t familiar, we recommend checking out React’s &lt;a href="https://reactjs.org/docs/hooks-overview.html" rel="noopener noreferrer"&gt;Hooks at a Glance&lt;/a&gt; docs before starting this tutorial.&lt;/p&gt;

&lt;p&gt;After you import the &lt;code&gt;useForm()&lt;/code&gt; hook, there are basic steps to run through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use the &lt;code&gt;useForm()&lt;/code&gt; hook to get &lt;code&gt;register&lt;/code&gt; and &lt;code&gt;handleSubmit()&lt;/code&gt;.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You need to pass &lt;code&gt;register&lt;/code&gt; into the &lt;code&gt;ref&lt;/code&gt; prop when you create your form so the values the user adds—and your validation rules—can be submitted. Later on in this tutorial, we will use  &lt;code&gt;register&lt;/code&gt; to handle validation. &lt;code&gt;handleSubmit()&lt;/code&gt; for &lt;code&gt;onSubmit&lt;/code&gt; connects your actual form into &lt;code&gt;react-hook-form&lt;/code&gt; (which provides register in the first place).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { register, handleSubmit } = useForm();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a function to handle your data&lt;/strong&gt;, so your data actually winds up in your database&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your backend is your own, but we’re going to pretend that we have a &lt;code&gt;saveData()&lt;/code&gt; function in another file that handles saving our data to a database. It’s just &lt;code&gt;console.log(data)&lt;/code&gt; for the purposes of this tutorial.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Render your form&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’re creating a React form component, so we will use form-related &lt;code&gt;jsx&lt;/code&gt; tags to build it, like &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s start with a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; container. Be sure to pass your &lt;code&gt;saveData()&lt;/code&gt; function into &lt;code&gt;react-hook-form&lt;/code&gt;’s &lt;code&gt;handleSubmit()&lt;/code&gt; that you got from the &lt;code&gt;useForm()&lt;/code&gt; hook and then into the &lt;code&gt;onSubmit()&lt;/code&gt; in the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag. If that sounded really confusing, peep the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
 ...
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s add a header with &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; so our reps know what this form is for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form ...&amp;gt;
 &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re going to create four &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; pairs for name, address, date, and order number. For each &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, be sure to pass &lt;code&gt;register&lt;/code&gt; from the &lt;code&gt;useForm()&lt;/code&gt; hook into the &lt;code&gt;ref&lt;/code&gt; prop and give it a name in the name prop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
&amp;lt;input name="name" ref={register} /&amp;gt;
&amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
&amp;lt;input name="address" ref={register} /&amp;gt;
&amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
&amp;lt;input name="date" ref={register} /&amp;gt;
&amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
&amp;lt;input name="order" ref={register} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we’ll add a submit button by using an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; with a “submit” type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="submit" /&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Putting it all together, we will have the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";

import saveData from "./some_other_file";

export default function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
     &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
     &amp;lt;input name="name" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
     &amp;lt;input name="address" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
     &amp;lt;input name="date" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
     &amp;lt;input name="order" ref={register} /&amp;gt;
     &amp;lt;input type="submit" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FNew-Order-React-Form_Retool.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FNew-Order-React-Form_Retool.png" alt="New-Order-React-Form_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, now we have a (kinda) working form.&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling with CSS
&lt;/h2&gt;



&lt;p&gt;You can easily style your form with CSS modules, &lt;code&gt;styled-components&lt;/code&gt;, or your favorite kind of styling. For our tutorial, we’re going to use &lt;code&gt;styled-components&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, we install and import &lt;a href="https://www.npmjs.com/package/styled-components" rel="noopener noreferrer"&gt;&lt;code&gt;style-components&lt;/code&gt;&lt;/a&gt; into our project. Then, we create a styled component (based on a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;) and plop all of our pretty CSS into that. Finally, we wrap our form in the &lt;code&gt;&amp;lt;Styles&amp;gt;&lt;/code&gt; tag to apply the styles. Easy!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";
import styled from "styled-components";

import saveData from "./some_other_file";

const Styles = styled.div`
 background: lavender;
 padding: 20px;

 h1 {
   border-bottom: 1px solid white;
   color: #3d3d3d;
   font-family: sans-serif;
   font-size: 20px;
   font-weight: 600;
   line-height: 24px;
   padding: 10px;
   text-align: center;
 }

 form {
   background: white;
   border: 1px solid #dedede;
   display: flex;
   flex-direction: column;
   justify-content: space-around;
   margin: 0 auto;
   max-width: 500px;
   padding: 30px 50px;
 }

 input {
   border: 1px solid #d9d9d9;
   border-radius: 4px;
   box-sizing: border-box;
   padding: 10px;
   width: 100%;
 }

 label {
   color: #3d3d3d;
   display: block;
   font-family: sans-serif;
   font-size: 14px;
   font-weight: 500;
   margin-bottom: 5px;
 }

 .error {
   color: red;
   font-family: sans-serif;
   font-size: 12px;
   height: 30px;
 }

 .submitButton {
   background-color: #6976d9;
   color: white;
   font-family: sans-serif;
   font-size: 14px;
   margin: 20px 0px;
`;

function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
     &amp;lt;input name="name" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
     &amp;lt;input name="address" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
     &amp;lt;input name="date" ref={register} /&amp;gt;
     &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
     &amp;lt;input name="order" ref={register} /&amp;gt;
     &amp;lt;input type="submit" className="submitButton" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}

export default function App() {
 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;Form /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s a lot of styling code, but look where it gets us!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Styled_Retool.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Styled_Retool.png" alt="React-Form-Styled_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using a React component library
&lt;/h2&gt;



&lt;p&gt;If you hate battling CSS, using a React component library might be a good option. It can add a lot of functionality, like animations, that are time-consuming to implement. If you’re not familiar with the plethora of React component libraries, you can &lt;a href="https://retool.com/blog/top-react-component-libraries-for-2020/" rel="noopener noreferrer"&gt;check out our recent post that covers our favorites&lt;/a&gt;. For this example, we’re going to use &lt;a href="https://material-ui.com/" rel="noopener noreferrer"&gt;Material UI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The easiest way to incorporate a React component library is to use one that exposes the &lt;code&gt;ref&lt;/code&gt; field as a prop. Then, all you have to do is substitute it for the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; field and then pass &lt;code&gt;register&lt;/code&gt; to that ref.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Button, TextField } from "@material-ui/core";

...

function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;&amp;gt;
     &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
     &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
       &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
       &amp;lt;TextField name="name" inputRef={register} /&amp;gt;
       ...
       // Let's use Material UI's Button too
       &amp;lt;Button variant="contained" color="primary"&amp;gt;Submit&amp;lt;/Button&amp;gt;
     &amp;lt;/form&amp;gt;
   &amp;lt;/&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we get the sleekness and functionality of Material-UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2Fmaterial-ui.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2Fmaterial-ui.gif" alt="material-ui"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate your React form component
&lt;/h2&gt;



&lt;p&gt;The last thing we want is for our customer support reps to add faulty data into our database. If we have any other apps using the same data, like reports running on the number of orders made in a certain time span, then adding in a date that isn’t formatted correctly could ruin the whole thing.&lt;/p&gt;

&lt;p&gt;For our use case, we are going to add validation in the form of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making all fields required&lt;/li&gt;
&lt;li&gt;Adding an address validator&lt;/li&gt;
&lt;li&gt;Validating date&lt;/li&gt;
&lt;li&gt;Validating order number&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Making all fields required
&lt;/h3&gt;

&lt;p&gt;All you have to do to make a field required is pass an object into the &lt;code&gt;register()&lt;/code&gt; prop in input that says &lt;code&gt;{required: true}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input name="name" ref={register({ required: true })} /&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will flag the &lt;code&gt;errors&lt;/code&gt; prop for the “name” field, which can then be used to add an error message (see next section).&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding an address validator
&lt;/h3&gt;

&lt;p&gt;To make our life easy, we are going to add a validator to check whether the address the user enters exists and is properly formatted.We’ll use a mock function from our example and show you how to integrate it into the React form component.&lt;/p&gt;

&lt;p&gt;First, we define our validator function. For our purposes, we are just checking a specific string. This is where you would hook into your validator library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function addressValidator(address) {
 if (address === "123 1st St., New York, NY") {
   return true;
 }
 return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we add validation to the register for address input. Make sure to pass the “value” that the user enters. If your validator function returns true, then it is validated and no error will appear.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input name="address" ref={register({
 required: true,
 validate: value =&amp;gt; addressValidator(value),
})} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to go further with your address validation than just adding a mock function (which you probably do because this is useless in production), we recommend checking out this awesome &lt;a href="https://developer.here.com/blog/street-address-validation-with-reactjs-and-here-geocoder-autocomplete" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; from HERE on validating location data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validating date
&lt;/h3&gt;

&lt;p&gt;To make sure users only enter valid dates into our date input field, we're going to add &lt;code&gt;type="date"&lt;/code&gt; to our date input field in the React form component in order to force the user to fill out the field in our specified format. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Date-Validator_Retool.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Date-Validator_Retool.png" alt="React-Form-Date-Validator_Retool"&gt;&lt;/a&gt;    &lt;/p&gt;

&lt;p&gt;In some browsers (like Chrome), this will add a DatePicker to the input box. In all browsers, it will provide a clear format for the date the rep should enter and will not let them use a different format. We can even add a max date to stop the customer support rep from accidentally adding a future order date (as much as we’d all love to just skip 2020).&lt;/p&gt;

&lt;p&gt;For this section, we’re going to use the &lt;a href="https://momentjs.com/" rel="noopener noreferrer"&gt;&lt;code&gt;moment&lt;/code&gt; library&lt;/a&gt; since it makes formatting dates much easier than JavaScript’s native date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import moment from 'moment';

...
&amp;lt;input
 name="date"
 type="date"
 max={moment().format("YYYY-MM-DD")}
 ref={register({ required: true })}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cool thing about validating the date in the input as opposed to the register is that we won’t have to waste time and energy building out error messages since the input will stop our user from entering an erroneous value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Datepicker_Retool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Datepicker_Retool.gif" alt="React-Form-Datepicker_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking good!&lt;/p&gt;

&lt;h3&gt;
  
  
  Validating order number
&lt;/h3&gt;

&lt;p&gt;For our order number field, we need to add validation that ensures the input is a valid order number in our system. &lt;code&gt;react-hook-form&lt;/code&gt; has a really easy way to apply regex validation by passing a “pattern” into the register.&lt;/p&gt;

&lt;p&gt;Let’s say that our order numbers are always 14 integers long (though this regex could easily be updated to fit whatever your order numbers look like).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
 name="order"
 ref={register({
   required: true,
   minLength: 14,
   maxLength: 14,
   pattern: /\d{14}/,
 })}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great work! Now an error will bubble up when the order number does not meet our specified pattern. For more details, you can read more in the &lt;a href="https://react-hook-form.com/api#register" rel="noopener noreferrer"&gt;&lt;code&gt;register&lt;/code&gt; section&lt;/a&gt; of the &lt;code&gt;react-hook-form&lt;/code&gt; documentation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Communicate errors in your React form component
&lt;/h3&gt;

&lt;p&gt;Adding error handling to your form is easy with &lt;code&gt;react-hook-form&lt;/code&gt;. Let’s start with communicating that certain fields are required. All we have to do is get &lt;code&gt;errors&lt;/code&gt; from the &lt;code&gt;useForm()&lt;/code&gt; hook and then add a conditional to render them under the input if they are needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Form() {
 const { register, errors, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
     &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
     &amp;lt;input name="name" ref={register({ required: true })} /&amp;gt;
     {errors.name &amp;amp;&amp;amp; "Required"}
     &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="address"
       ref={register({
         required: true,
         validate: value =&amp;gt; addressValidator(value)
       })}
     /&amp;gt;
     {errors.address &amp;amp;&amp;amp; "Required"}
     &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="date"
       type="date"
       max={moment().format("YYYY-MM-DD")}
       ref={register({ required: true })}
     /&amp;gt;
     {errors.date &amp;amp;&amp;amp; "Required"}
     &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="order"
       ref={register({
         required: true,
         pattern: /\d{14}/,
       })}
     /&amp;gt;
     {errors.order &amp;amp;&amp;amp; "Required"}
     &amp;lt;input type="submit" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how we refer to the error for a specific input field by using &lt;code&gt;errors.name&lt;/code&gt; and &lt;code&gt;errors.date&lt;/code&gt;. And here is what our error looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Bad-Errors_Retool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Bad-Errors_Retool.gif" alt="React-Form-Bad-Errors_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One last issue - since these errors are conditionals, they’ll increase the size of our form. To get around this, we will make a simple error component that renders the height of the error, even if there is no text. We’ll also color the text red, so it’s easier to see.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";
import styled from "styled-components";

import saveData from "./some_other_file";

const Styles = styled.div`
 background: lavender;
 ...
 .error {
   color: red;
   font-family: sans-serif;
   font-size: 12px;
   height: 30px;
 }
`;

// Render " " if no errors, or error message if errors
export function Error({ errors }) {
 return &amp;lt;div className={"error"}&amp;gt;{errors ? errors.message : " "}&amp;lt;/div&amp;gt;;
}

export function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
     &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
     &amp;lt;input name="name" ref={register({ required: true })} /&amp;gt;
    &amp;lt;Error errors={errors.name} /&amp;gt;
     &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="address"
       ref={register({
         required: true,
         validate: value =&amp;gt; addressValidator(value)
       })}
     /&amp;gt;
    &amp;lt;Error errors={errors.address} /&amp;gt;
     &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="date"
       type="date"
       max={moment().format("YYYY-MM-DD")}
       ref={register({ required: true })}
     /&amp;gt;
     &amp;lt;Error errors={errors.date} /&amp;gt;
     &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="order"
       ref={register({
         required: true,
         pattern: /\d{14}/,
       })}
     /&amp;gt;
     &amp;lt;Error errors={errors.order} /&amp;gt;
     &amp;lt;input type="submit" className="submitButton" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait! There’s no error message text to render. To fix this, let’s start with the Required validation. We do this by adding the error message for that particular type of error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input name="name" ref={register({ required: 'Required' })} /&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go through your code and change &lt;code&gt;required: true&lt;/code&gt; to &lt;code&gt;required: 'Required'&lt;/code&gt; in every place that you see it. Now this functions a lot more like a form we would expect to see in the real world:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Good-Errors_Retool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Good-Errors_Retool.gif" alt="React-Form-Good-Errors_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But hold on! We validated a lot more than just required fields. Let’s get a little more granular with these errors, so our customer support reps know how to fix the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding an address error
&lt;/h3&gt;

&lt;p&gt;To add an address error to your &lt;code&gt;validate&lt;/code&gt; section, simply add an &lt;code&gt;||&lt;/code&gt; so that if your validation function returns “false,” it will display your message instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
 name="address"
 ref={register({
   required: 'Required',
   validate: value =&amp;gt; addressValidator(value) || 'Invalid address',
 })}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what your error will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-address-error_Retool.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-address-error_Retool.gif" alt="React-form-address-error_Retool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding an order number error
&lt;/h3&gt;

&lt;p&gt;In our system, our order numbers are always 14 digits long and made up of positive integers between 0-9. To verify this order number pattern, we are going to use &lt;code&gt;minLength&lt;/code&gt; and &lt;code&gt;maxLength&lt;/code&gt; to verify length and &lt;code&gt;pattern&lt;/code&gt; to verify the pattern. &lt;/p&gt;

&lt;p&gt;First, change “minLength”, “maxLength”, and “pattern” into objects with a value key, where the regex pattern or number you defined is the value, and a &lt;code&gt;message&lt;/code&gt; key, where the value is your error message.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input
 name="order"
 ref={register({
   required: 'Required',
   minLength: {
     value: 14,
     message: 'Order number too short',
   },
   maxLength: {
     value: 14,
     message: 'Order number too long',
   },
   pattern: {
     value: /\d{14}/,
     message: "Invalid order number",
   },
 })}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is what your error will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-order-error.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-form-order-error.gif" alt="React-form-order-error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it for errors! Check out &lt;code&gt;react-hook-form&lt;/code&gt;’s &lt;a href="https://react-hook-form.com/get-started#Handleerrors" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; for more information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your React form component with &lt;code&gt;react-hook-form&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Here is our final React form component:&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Table-Final_Retool-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FReact-Form-Table-Final_Retool-1.gif" alt="React-Form-Table-Final_Retool-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more code samples that cover the vast range of features that react-hook-form has to offer, check out &lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;React Hook Form&lt;/a&gt;’s website. And for a full version of this code that you can test out and play around with, check out our &lt;a href="https://codesandbox.io/s/react-hook-form-get-started-o56v2?file=/src/App.js" rel="noopener noreferrer"&gt;code sandbox&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="tldr"&gt;TL;DR: Syntax roundup&lt;/h2&gt;



&lt;p&gt;We know that this tutorial covered a ton of features for forms in &lt;code&gt;react-hook-form&lt;/code&gt;, so just to make sure you didn’t miss anything, here is a roundup of the features we covered:&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a simple React form component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";

import saveData from "./some-other-file";

export default function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;label&amp;gt;Field&amp;lt;/label&amp;gt;
     &amp;lt;input name="field" ref={register} /&amp;gt;
     &amp;lt;input type="submit" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Style your React form component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";
import styled from "styled-components";

import saveData from "./some_other_file";

const Styles = styled.div`
background: lavender;
 padding: 20px;

 h1 {
   border-bottom: 1px solid white;
   color: #3d3d3d;
   font-family: sans-serif;
   font-size: 20px;
   font-weight: 600;
   line-height: 24px;
   padding: 10px;
   text-align: center;
 }

 form {
   background: white;
   border: 1px solid #dedede;
   display: flex;
   flex-direction: column;
   justify-content: space-around;
   margin: 0 auto;
   max-width: 500px;
   padding: 30px 50px;
 }

 input {
   border: 1px solid #d9d9d9;
   border-radius: 4px;
   box-sizing: border-box;
   padding: 10px;
   width: 100%;
 }

 label {
   color: #3d3d3d;
   display: block;
   font-family: sans-serif;
   font-size: 14px;
   font-weight: 500;
   margin-bottom: 5px;
 }

 .submitButton {
   background-color: #6976d9;
   color: white;
   font-family: sans-serif;
   font-size: 14px;
   margin: 20px 0px;
 }
`;

export function Form() {
 const { register, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;label&amp;gt;Field&amp;lt;/label&amp;gt;
     &amp;lt;input name="field" ref={register} /&amp;gt;
     &amp;lt;input type="submit" className="submitButton" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}

export default function App() {
 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;Form /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validate your React form component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
 &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
 &amp;lt;input name="name" ref={register({ required: true })} /&amp;gt;
 &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
 &amp;lt;input
   name="address"
   ref={register({
     required: true,
     validate: value =&amp;gt; addressValidator(value)
   })}
 /&amp;gt;
 &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
 &amp;lt;input
   name="date"
   type="date"
   max={moment().format("YYYY-MM-DD")}
   ref={register({ required: true })}
 /&amp;gt;
 &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
 &amp;lt;input
   name="order"
   ref={register({
     required: true,
     pattern: /\d{14}/,
   })}
 /&amp;gt;
 &amp;lt;input type="submit" /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add errors to your React form component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function Form() {
 const { register, errors, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;label&amp;gt;Field&amp;lt;/label&amp;gt;
     &amp;lt;input name="field" ref={register({ required: true })} /&amp;gt;
     {errors.name &amp;amp;&amp;amp; "Name is required"}
   &amp;lt;/form&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full form
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { useForm } from "react-hook-form";
import styled from "styled-components";
import moment from 'moment';

import saveData from "./some_other_file";

const Styles = styled.div`
 background: lavender;
 padding: 20px;

 h1 {
   border-bottom: 1px solid white;
   color: #3d3d3d;
   font-family: sans-serif;
   font-size: 20px;
   font-weight: 600;
   line-height: 24px;
   padding: 10px;
   text-align: center;
 }

 form {
   background: white;
   border: 1px solid #dedede;
   display: flex;
   flex-direction: column;
   justify-content: space-around;
   margin: 0 auto;
   max-width: 500px;
   padding: 30px 50px;
 }

 input {
   border: 1px solid #d9d9d9;
   border-radius: 4px;
   box-sizing: border-box;
   padding: 10px;
   width: 100%;
 }

 label {
   color: #3d3d3d;
   display: block;
   font-family: sans-serif;
   font-size: 14px;
   font-weight: 500;
   margin-bottom: 5px;
 }

 .error {
   color: red;
   font-family: sans-serif;
   font-size: 12px;
   height: 30px;
 }

 .submitButton {
   background-color: #6976d9;
   color: white;
   font-family: sans-serif;
   font-size: 14px;
   margin: 20px 0px;
 }
`;

export function addressValidator(address) {
 if (address === "123 1st St., New York, NY") {
   return true;
 }
 return false;
}

export function Error({ errors }) {
 return &amp;lt;div className={"error"}&amp;gt;{errors ? errors.message : " "}&amp;lt;/div&amp;gt;;
}

export function Form() {
 const { register, errors, handleSubmit } = useForm();

 return (
   &amp;lt;form onSubmit={handleSubmit(data =&amp;gt; saveData(data))}&amp;gt;
     &amp;lt;h1&amp;gt;New Order&amp;lt;/h1&amp;gt;
     &amp;lt;label&amp;gt;Name&amp;lt;/label&amp;gt;
     &amp;lt;input name="name" ref={register({ required: 'Required' })} /&amp;gt;
     &amp;lt;Error errors={errors.name} /&amp;gt;
     &amp;lt;label&amp;gt;Address&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="address"
       ref={register({
         required: 'Required',
         validate: value =&amp;gt; addressValidator(value) || 'Invalid address',
       })}
     /&amp;gt;
     &amp;lt;Error errors={errors.address} /&amp;gt;
     &amp;lt;label&amp;gt;Date&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="date"
       type="date"
       max={moment().format("YYYY-MM-DD")}
       ref={register({ required: 'Required' })}
     /&amp;gt;
     &amp;lt;Error errors={errors.date} /&amp;gt;
     &amp;lt;label&amp;gt;Order Number&amp;lt;/label&amp;gt;
     &amp;lt;input
       name="order"
       ref={register({
         required: 'Required',
         minLength: {
           value: 14,
           message: 'Order number too short',
         },
         maxLength: {
           value: 14,
           message: 'Order number too long',
         },
         pattern: {
           value: /\d{14}/,
           message: "Invalid order number",
         },
     })} /&amp;gt;
     &amp;lt;Error errors={errors.order} /&amp;gt;
     &amp;lt;input type="submit" className="submitButton" /&amp;gt;
   &amp;lt;/form&amp;gt;
 );
}

export default function App() {
 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;Form /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other React form libraries
&lt;/h2&gt;



&lt;p&gt;&lt;code&gt;react-hook-form&lt;/code&gt; has nearly 13K stars on &lt;a href="https://github.com/react-hook-form/react-hook-form" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, but it's worth taking a second to explain why we decided to go with &lt;code&gt;react-hook-form&lt;/code&gt; instead of other popular React form libraries, like &lt;code&gt;formik&lt;/code&gt; and &lt;code&gt;react-final-form&lt;/code&gt;. It’s worth recognizing that these form libraries are pretty awesome in their own ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;formik&lt;/code&gt; has top-notch documentation and extremely thorough tutorials.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-final-form&lt;/code&gt; is great for those used to working with &lt;code&gt;redux-final-form&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately, we chose &lt;code&gt;react-hook-form&lt;/code&gt; because it has a tiny bundle size, no dependencies, and is relatively new (many sources, like &lt;a href="https://blog.logrocket.com/react-hook-form-vs-formik-a-technical-and-performance-comparison/" rel="noopener noreferrer"&gt;LogRocket&lt;/a&gt; and &lt;a href="https://itnext.io/is-react-hook-form-the-future-57c6f94a2665" rel="noopener noreferrer"&gt;ITNEXT&lt;/a&gt;, are claiming it is the best library for building forms in React) compared to the rest. If you’re interested in learning about some other ways to build React forms, &lt;a href="https://formspree.io/blog/react-forms-1/" rel="noopener noreferrer"&gt;check this out&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>CRUD with the Firebase RealtimeDB's REST API</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Tue, 08 Sep 2020 18:16:53 +0000</pubDate>
      <link>https://dev.to/retool/crud-with-the-firebase-realtimedb-s-rest-api-265</link>
      <guid>https://dev.to/retool/crud-with-the-firebase-realtimedb-s-rest-api-265</guid>
      <description>&lt;p&gt;If you got started using &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;Firebase&lt;/a&gt; &lt;em&gt;before&lt;/em&gt; last year, chances are you’re working with the (now legacy) &lt;a href="https://firebase.google.com/docs/database/rest/start" rel="noopener noreferrer"&gt;RealtimeDB&lt;/a&gt; and not &lt;a href="https://firebase.google.com/docs/firestore" rel="noopener noreferrer"&gt;Firestore&lt;/a&gt;. This guide will walk you through how to do basic CRUD on your giant JSON object (“database”) - creating, reading, updating, and deleting objects. We’ll also go over setting up db security, as well as some notes on data structure best practices.&lt;/p&gt;

&lt;p&gt;For our example, we’re working with the database’s REST API, but the principles apply to the Node / iOS / Android / any other client library.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Realtime Database REST API basics
&lt;/h2&gt;



&lt;p&gt;Any URL within the Firebase RealtimeDB can be used as a REST endpoint by adding &lt;code&gt;.json&lt;/code&gt; to the end. One important thing to note is that all requests must be sent over HTTPS, not HTTP. You can use any request client that you want for this tutorial, but we are going to use &lt;a href="https://curl.haxx.se/" rel="noopener noreferrer"&gt;cURL&lt;/a&gt; because it’s easy to use and works right from your terminal.&lt;/p&gt;

&lt;p&gt;Let’s pretend that we’re creating an internal app for an online retailer. The users of the internal app will be customer support reps who will need access to a table full of customer data. Using the Firebase RealtimeDB REST API, we’ll give our customer support reps the ability to &lt;strong&gt;create&lt;/strong&gt;, &lt;strong&gt;read&lt;/strong&gt;, &lt;strong&gt;update&lt;/strong&gt;, and &lt;strong&gt;delete&lt;/strong&gt; data from the Firebase RealtimeDB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: We're using test mode, so we don't need to authenticate our requests. To read more about authentication check out our section below. on data security.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial, we’ll use the following data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "eantoni": {
   "name": "Erika Antoni",
   "state": "California",
   "emails": {
     "primary": "eantoni@example.com",
     "secondary": "erika@work.com"
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each object in the “users” database will have a unique key (made from the user’s first initial and last name), name, state, and emails, which are a nested object containing a primary and secondary email.&lt;/p&gt;

&lt;p&gt;One thing to note: the RealtimeDB has &lt;a href="https://firebase.google.com/docs/rules/basics" rel="noopener noreferrer"&gt;a “test” mode&lt;/a&gt; that you can configure when you create it, which means that no authentication is required. It’s useful for testing, but remember not to put any sensitive data there.&lt;/p&gt;

&lt;p&gt;To get started, we’ll first need to grab the URL of the database so we know where to send our requests. When you log in to Firebase, you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--44SgvcWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.24.23-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--44SgvcWn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.24.23-PM.png" alt="Screen-Shot-2020-08-12-at-4.24.23-PM" width="678" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The base of the URL you are going to use is that one at the top:&lt;br&gt;
&lt;code&gt;https://{db-name}.firebaseio.com&lt;/code&gt;. Instead of &lt;code&gt;{db-name}&lt;/code&gt;, you’ll use the auto-generated db name.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating data in the RealtimeDB
&lt;/h2&gt;



&lt;p&gt;We may have a database created, but right now, there’s nothing in it. Let’s change that. We’re going to create a record for an example user—Erika Antoni—in our database. To do this, we will use &lt;code&gt;PUT&lt;/code&gt; instead of &lt;code&gt;POST&lt;/code&gt; since we want to define the unique key for the user.&lt;/p&gt;

&lt;p&gt;Note that the URL we are going to use has &lt;code&gt;users.json&lt;/code&gt; at the end of it. This endpoint doesn’t really exist - we’re actually creating a top level “users” object (via the endpoint itself) then and populating it with our payload, all in one request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PUT -d '{
 "eantoni": {
   "name": "Erika Antoni",
   "state": "California",
   "emails": {
     "primary": "eantoni@example.com",
     "secondary": "erika@work.com"
   }
 }' 'https://{db-name}.firebaseio.com/users.json'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we return to our database in the Firebase console, we should see our data as a JSON tree:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uGMU1Wts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.41.22-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uGMU1Wts--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.41.22-PM.png" alt="Screen-Shot-2020-08-12-at-4.41.22-PM" width="425" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading data from the RealtimeDB
&lt;/h2&gt;



&lt;p&gt;To read data from our Firebase RealtimeDB, we are going to use &lt;code&gt;GET&lt;/code&gt; with the added URI parameter “print” at the end because we don’t like looking at long, confusing lines of JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 'https://{db-name}.firebaseio.com/users/eantoni.json?print=pretty' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is our output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "address" : "55 S. 5th St., Denver, CO",
 "emails" : {
   "primary" : "enantoni@example.com",
   "work" : "erika@work.com"
 },
 "name" : "Erika Antoni",
 "state" : "California"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how we specified the URL to read from the &lt;code&gt;eantoni&lt;/code&gt; node. If we wanted to read the whole &lt;code&gt;users&lt;/code&gt; database, we would simply have it go to &lt;code&gt;users.json&lt;/code&gt; instead of &lt;code&gt;users/enantoni.json&lt;/code&gt;. These endpoint ergonomics can be really useful if you structure your objects correctly (refer to the &lt;a href="https://firebase.google.com/docs/database/rest/structure-data" rel="noopener noreferrer"&gt;Firebase docs about structuring your data&lt;/a&gt;). We’ll cover more about structuring later on.&lt;/p&gt;

&lt;p&gt;You probably don’t want to return your entire database at once, so let’s try filtering our request. Maybe we want to order the data alphabetically by the user’s state. Here is our sample data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "eantoni": {
   "name": "Erika Antoni",
   "state": "California",
   "emails": {
     "primary": "eantoni@example.com",
     "secondary": "erika@work.com"
   }
 },
 "mmiller": {
   "name": "Michelle Miller",
   "state": "Arizona",
   "emails": {
     "primary": "mmiller@example.com",
     "secondary": "michelle@work.com"
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All we need to do is add an &lt;a href="https://firebase.google.com/docs/database/rest/retrieve-data#filtering-by-a-specified-child-key" rel="noopener noreferrer"&gt;&lt;code&gt;orderBy&lt;/code&gt; URI parameter&lt;/a&gt; to the end of our request and specify that “state” is the child key we want the ordering to be based on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 'https://{db-name}.firebaseio.com/users.json?orderBy="state"&amp;amp;print=pretty' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the response we’ll get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "mmiller": {
   "name": "Michelle Miller",
   "state": "Arizona",
   "emails": {
     "primary": "mmiller@example.com",
     "secondary": "michelle@work.com"
   }
 },
 "eantoni": {
   "name": "Erika Antoni",
   "state": "California",
   "emails": {
     "primary": "eantoni@example.com",
     "secondary": "erika@work.com"
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check out the rest of the URI parameters for &lt;code&gt;GET&lt;/code&gt; requests in the Firebase &lt;a href="https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-uri-params" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. You can also &lt;a href="https://firebase.google.com/docs/database/rest/retrieve-data#limit-queries" rel="noopener noreferrer"&gt;limit the results of your query&lt;/a&gt; (by first or last results). &lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating data in Firebase RealtimeDB
&lt;/h2&gt;



&lt;p&gt;Say we want to add a field to our user, like an address. To do this, we’ll use &lt;code&gt;PATCH&lt;/code&gt; and clearly specify the path when writing the data for the object. We can do this by changing the endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PATCH -d '{
 "address": "123 1st St., San Francisco, CA"}' \
'https://{db-name}.firebaseio.com/users/eantoni.json'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;. . . or by specifying the path for the data in the request payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PATCH -d '{
 "eantoni/address": "123 1st St., San Francisco, CA"}' \
 'https://{db-name}.firebaseio.com/users.json'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we’ve added Erika’s address without disturbing the rest of her data:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_2aXnnTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.54.16-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_2aXnnTj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/Screen-Shot-2020-08-12-at-4.54.16-PM.png" alt="Screen-Shot-2020-08-12-at-4.54.16-PM" width="448" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep in mind that neglecting to append the new path to the URL or data will result in overwriting the entire node.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Similarly, if we want to update an existing field (instead of adding a new one), we just form the request using &lt;code&gt;PATCH&lt;/code&gt; and the specific path. Say we found out that Erika moved to Colorado. We can actually update both the “address” and “state” fields for Erika at the same time like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PATCH -d '{
 "address": "55 S. 5th St., Denver, CO",
 "state": "Colorado"
}' \
 'https://{db-name}.firebaseio.com/users/eantoni.json'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is our updated record:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QOJIEpKT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/image4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QOJIEpKT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/09/image4.png" alt="image4" width="514" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now Erika lives in Colorado. Sweet. ⛰️&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting data from the Firebase RealtimeDB
&lt;/h2&gt;



&lt;p&gt;If you want to give your users the ability to delete a record, use &lt;a href="https://firebase.google.com/docs/database/rest/save-data#section-delete" rel="noopener noreferrer"&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X DELETE 'https://{db-name}.firebaseio.com/users/eantoni.json' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will delete Erika’s entire record. If we only wanted to delete a field in her record, we could do so like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X DELETE 'https://{db-name}.firebaseio.com/users/eantoni/emails/work.json' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this is where the endpoint-based record location comes in the clutch - referencing and deleting nested fields just requires a deeper endpoint. And just like that, all of our data for Erika is gone, and we’re right back where we started.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Data security for the Firebase RealtimeDB
&lt;/h2&gt;



&lt;p&gt;Like you’d be able to do with something like Postgres, Firebase allows users to set &lt;a href="https://firebase.google.com/docs/database/security" rel="noopener noreferrer"&gt;Rules&lt;/a&gt; so your DB isn’t open to random traffic. You can configure Rules via the GUI on Firebase’s website, or you can use the &lt;a href="https://firebase.google.com/docs/database/rest/app-management" rel="noopener noreferrer"&gt;Rules REST API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rules are structured similar to a JSON object and give you the ability to specify read and write permissions at path-level, using &lt;code&gt;.read&lt;/code&gt; and &lt;code&gt;.write&lt;/code&gt; as keys in an object definition. For instance, if we wanted our database to be global read-only, we would do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "rules": {
   "users": {
     ".read": true,
     ".write": false
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Users” is our root database ref, so the rules in its object get applied to the whole database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.read&lt;/code&gt; and &lt;code&gt;.write&lt;/code&gt; don’t have to just be boolean values. We can also use variables and write conditionals. Let’s say that we only want our user, Erika Antoni, to be able to access her data object. We would do so like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "rules": {
   "users": {
     "$uid": {
       ".read": "$uid === auth.uid",
       ".write": "$uid === auth.uid"
     }
   }
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;$uid&lt;/code&gt; and &lt;code&gt;auth.uid&lt;/code&gt; are built-in variables that come from &lt;a href="https://firebase.google.com/products/auth" rel="noopener noreferrer"&gt;Firebase Authentication&lt;/a&gt; (which you can configure to work with your app).&lt;/p&gt;

&lt;p&gt;First, you’ll need to generate an access token to be able to write Rules via REST (follow this &lt;a href="https://firebase.google.com/docs/database/rest/auth#google_oauth2_access_tokens" rel="noopener noreferrer"&gt;guide&lt;/a&gt; for using Google’s OAuth2). Then, use &lt;code&gt;PUT&lt;/code&gt; with the Rules object as your payload and be sure to include your newly generated access token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X PUT -d '{ "rules": { ".read": true, ".write": false } }'
 'https://{db-name}.firebaseio.com/.settings/rules.json?
   access_token={access-token}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s important to remember that any Rules you add via REST API will overwrite any existing ones that have been configured. To avoid overwriting Rules, you can first &lt;code&gt;GET&lt;/code&gt; configured Rules like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 'https://{db-name}.firebaseio.com/.settings/rules.json?
 access_token={access-token}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can always use the GUI if you’re afraid of overwriting everything.&lt;/p&gt;

&lt;p&gt;Once you’ve set up your Rules, you simply need to add an &lt;code&gt;auth&lt;/code&gt; URI parameter to each request, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X GET 'https://{db-name}.firebaseio.com/users/eantoni.json?auth={cred}' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, cred is either an auth token or a Firebase app secret. You can read more &lt;a href="https://firebase.google.com/docs/database/rest/save-data#auth" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t want to use Firebase’s Authentication, you can set up your own &lt;a href="https://firebase.google.com/docs/auth/web/custom-auth" rel="noopener noreferrer"&gt;custom authentication&lt;/a&gt;. First, you will need to generate a &lt;a href="https://developers.google.com/identity/protocols/oauth2" rel="noopener noreferrer"&gt;Google OAuth2&lt;/a&gt; access token using an account that has permissions to your Realtime Database project. Use OAuth2 to generate a new private key, then use a &lt;a href="https://developers.google.com/api-client-library/" rel="noopener noreferrer"&gt;client library&lt;/a&gt; of your choosing to generate the token.&lt;/p&gt;

&lt;p&gt;If we were to use the Node.js client library, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var {google} = require(“googleapis”);
var key = require(“path/to/your/service/account/key.json”);

var jwt = new google.auth.JWT(
  serviceAccount.firebase_database,
  null,
  key.private_key,
  [“https://www.googleapis.com/auth/firebase.database”], //scope
);

// generate access token
jwt.authorize(function(err, tokens) {
  if (err || tokens.access_token === null) {
    console.log(“error”);
  } else {
    var access_token = tokens.access_token;
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your access token is generated, you can use it to authenticate with the REST API, just like using the Firebase Authentication, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X GET 'https://{db-name}.firebaseio.com/users/eantoni.json?auth={cred}' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can read more about setting up authentication for REST requests in the &lt;a href="https://firebase.google.com/docs/database/rest/auth" rel="noopener noreferrer"&gt;RealtimeDB docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Structuring data for the Firebase RealtimeDB
&lt;/h2&gt;



&lt;p&gt;Firebase’s RealtimeDB stores data as a JSON tree (which makes simple data management easy, but will make you sweat if you need to organize something more complex later on). The objects we’ve been working with in this post fit that bill:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "users": {
   "eantoni": {
     "name": "Erika Antoni",
     "state": "California",
     "emails": {
       "primary": "eantoni@example.com",
       "secondary": "erika@work.com",
     },
   },
   ...
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When designing a database that uses a JSON tree structure (as opposed to the document and collection structure in Cloud Firestore), there are a few key things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try not to nest data&lt;/strong&gt;. When you fetch data, all child nodes are returned with the one you fetched. This means that not only are you being inefficient by grabbing extra data, but you’re also unnecessarily exposing that data to the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flatten your data structures&lt;/strong&gt;. Keep only relevant data in each path and make the client do separate calls to get the data they need. This will keep code clear and understandable while helping you avoid writing lots of loops.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create indexable data&lt;/strong&gt;. If you have lots of data, iterating through all of it to gather the information you need on a regular basis isn’t feasible. Instead, create groups with indexes to indicate membership. For example, let’s say we have our “users” table from above. We often need to find a list of all customers who live in the same state. We could do this by iterating through every customer and checking their “state,” but instead, we can do the following:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
 "users": {
   "eantoni": {
     "name": "Erika Antoni",
     "state": "California",
     ...
   },
   ...
 },
 "states": {
   "california": {
     "residents": {
       "eantoni": true,
       ...
     },
   },
   ...
 }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now “states” can be easily indexed to find the members, which scales super well.&lt;/p&gt;

&lt;p&gt;For more information on structuring your data, check out Firebase’s &lt;a href="https://firebase.google.com/docs/database/rest/structure-data" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Getting started with react-datepicker</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Wed, 02 Sep 2020 21:15:03 +0000</pubDate>
      <link>https://dev.to/retool/getting-started-with-react-datepicker-37dn</link>
      <guid>https://dev.to/retool/getting-started-with-react-datepicker-37dn</guid>
      <description>&lt;p&gt;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 &lt;a href="https://reactdatepicker.com/" rel="noopener noreferrer"&gt;&lt;code&gt;react-datepicker&lt;/code&gt; library&lt;/a&gt;. This guide will walk through &lt;code&gt;react-datepicker&lt;/code&gt; basics with a focus on building internal tools&lt;/p&gt;

&lt;p&gt;By the end of this article, you’ll know how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import and use &lt;code&gt;react-datepicker&lt;/code&gt; in your React app to build a simple datepicker&lt;/li&gt;
&lt;li&gt;Customize your datepicker with time functionality, disabling dates, and a clear button&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;react-datepicker&lt;/code&gt; basics and setup
&lt;/h2&gt;



&lt;p&gt;&lt;code&gt;react-datepicker&lt;/code&gt; is a React library that is used by more than 40K developers with almost 5K stars on &lt;a href="https://github.com/Hacker0x01/react-datepicker" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. The simple version of the datepicker component is incredibly easy to use and comes with some great features, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Localization&lt;/li&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Advanced customization&lt;/li&gt;
&lt;li&gt;Range support&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;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 &lt;code&gt;react-table&lt;/code&gt;, and now we just need to add two datepickers so customer support reps can view orders between a range of dates.&lt;/p&gt;

&lt;p&gt;Our datepicker needs to have the ability to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a calendar view when the datepicker is clicked&lt;/li&gt;
&lt;li&gt;Display selected range&lt;/li&gt;
&lt;li&gt;Display selectable times&lt;/li&gt;
&lt;li&gt;Disable future dates&lt;/li&gt;
&lt;li&gt;Clear the datepicker when the X button is clicked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here's what the final product will look and feel like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10-2.gif" alt="Retool-Use-React-datepicker-Example-10-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;



&lt;p&gt;&lt;em&gt;If you're just here for the code, go ahead and jump to the TL;DR syntax summary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;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). &lt;/p&gt;

&lt;p&gt;We'll be using the &lt;code&gt;useState()&lt;/code&gt; hook in our function. If you’re not familiar with React Hooks, we recommend checking out React’s &lt;a href="https://reactjs.org/docs/hooks-overview.html" rel="noopener noreferrer"&gt;Hooks at a Glance&lt;/a&gt; docs before starting this tutorial.&lt;/p&gt;

&lt;p&gt;There are three simple steps for creating a datepicker:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import the datepicker component from &lt;code&gt;react-datepicker&lt;/code&gt; and &lt;code&gt;react-datepicker.css&lt;/code&gt; for styling.&lt;/li&gt;
&lt;li&gt;Set an initial date in the state (using the &lt;code&gt;useState()&lt;/code&gt; Hook).&lt;/li&gt;
&lt;li&gt;Render the datepicker, telling &lt;code&gt;onChange&lt;/code&gt; to update the date in state using the &lt;code&gt;setDate()&lt;/code&gt; function.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 (
   &amp;lt;DatePicker selected={date} onChange={date =&amp;gt; setDate(date)} /&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-2.gif" alt="Retool-Use-React-datepicker-Example-2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a datepicker range
&lt;/h2&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;react-datepicker&lt;/code&gt; 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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());

 return (
   &amp;lt;DatePicker
     selected={startDate}
     onChange={date =&amp;gt; setStartDate(date)}
     selectsStart // tells this DatePicker that it is part of a range*
     startDate={startDate}
   /&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());
 const [endDate, setEndDate] = useState(new Date());

 return (
   &amp;lt;div&amp;gt; // don't forget to wrap your DatePickers
     &amp;lt;DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate} // add the endDate to your startDate DatePicker now that it is defined
       onChange={date =&amp;gt; setStartDate(date)}
     /&amp;gt;
    &amp;lt;DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date =&amp;gt; setEndDate(date)}
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that’s it! The final version of the code all put together will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 (
   &amp;lt;div&amp;gt;
     &amp;lt;DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date =&amp;gt; setStartDate(date)}
     /&amp;gt;
     &amp;lt;DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date =&amp;gt; setEndDate(date)}
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have two datepickers that the customer support reps can use to select their ranges. Plus, the &lt;code&gt;react-datepicker&lt;/code&gt; library already handles highlighting the selected dates for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-3.gif" alt="Retool-Use-React-datepicker-Example-3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Selecting times
&lt;/h2&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;react-datepicker&lt;/code&gt; comes with two options for adding time to the calendar view:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-4.png" alt="Retool-Use-React-datepicker-Example-4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;To add the time selector to our datepickers, we’ll first add &lt;code&gt;showTimeSelect&lt;/code&gt; 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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date =&amp;gt; setStartDate(date)}
/&amp;gt;
&amp;lt;DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date =&amp;gt; setEndDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hey, that took almost no &lt;em&gt;time&lt;/em&gt; at all (sorry).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-5.gif" alt="Retool-Use-React-datepicker-Example-5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extend your datepicker with more features
&lt;/h2&gt;



&lt;p&gt;We've just barely scratched the surface of what &lt;code&gt;react-datepicker&lt;/code&gt; can do. A few useful ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Add a placeholder prompt to the datepicker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;placeholderText&lt;/code&gt; field and change the initial startDate and endDate values to &lt;code&gt;null&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(null);
 const [endDate, setEndDate] = useState(null);

 return (
   &amp;lt;div&amp;gt;
     &amp;lt;DatePicker
       placeholderText="Select Start Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date =&amp;gt; setStartDate(date)}
     /&amp;gt;
     &amp;lt;DatePicker
       placeholderText="Select End Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date =&amp;gt; setEndDate(date)}
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-6.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-6.gif" alt="Retool-Use-React-datepicker-Example-6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Disable future dates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;For this feature, we’re going to add the &lt;code&gt;filterDate&lt;/code&gt; field and define an arrow function that returns a Boolean value depending on whether the date displayed is in the future or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 filterDate={d =&amp;gt; {
   return new Date() &amp;gt; d;
 }}
 placeholderText="Select Start Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date =&amp;gt; setStartDate(date)}
/&amp;gt;
&amp;lt;DatePicker
 filterDate={d =&amp;gt; {
   return new Date() &amp;gt; d;
 }}
 placeholderText="Select End Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={endDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date =&amp;gt; setEndDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! Now the rep will only be able to filter the table based on dates that actually have order data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-7.gif" alt="Retool-Use-React-datepicker-Example-7"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Add a clear button to the datepicker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;X&lt;/code&gt; they can press to clear the datepicker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 isClearable
 filterDate={d =&amp;gt; {
   return new Date() &amp;gt; d;
 }}
 placeholderText="Select Start Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={startDate}
 selectsStart
 startDate={startDate}
 endDate={endDate}
 onChange={date =&amp;gt; setStartDate(date)}
/&amp;gt;
&amp;lt;DatePicker
 isClearable
 filterDate={d =&amp;gt; {
   return new Date() &amp;gt; d;
 }} 
 placeholderText="Select End Date"
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={endDate}
 selectsEnd
 startDate={startDate}
 endDate={endDate}
 minDate={startDate}
 onChange={date =&amp;gt; setEndDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-8.png" alt="Retool-Use-React-datepicker-Example-8"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-9.png" alt="Retool-Use-React-datepicker-Example-9"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to expand the width of the datepicker boxes, we have to override some of the styling that we imported in &lt;code&gt;react-datepicker.css&lt;/code&gt;. To do this, we are going to use &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt;, a popular React library used for low-level styling.&lt;/p&gt;

&lt;p&gt;First, import &lt;code&gt;styled-components&lt;/code&gt;, and then define a new &lt;code&gt;Styles&lt;/code&gt; 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 &lt;code&gt;&amp;lt;Styles&amp;gt;&lt;/code&gt; component around it.&lt;/p&gt;

&lt;p&gt;Take careful note of the &lt;code&gt;react-datepicker&lt;/code&gt; classnames that must be overwritten:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;react-datepicker-wrapper&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-datepicker__input-container&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;react-datepicker__input-container input&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 (
   &amp;lt;div&amp;gt;
     &amp;lt;DatePicker
       isClearable
       ...
     /&amp;gt;
     &amp;lt;DatePicker
       isClearable
       ...
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 );
}

export default function TableDatePicker() {
 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;DatePickerRange /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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;
 }
`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is our new, styled &lt;code&gt;X&lt;/code&gt; button:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10.gif" alt="Retool-Use-React-datepicker-Example-10"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting data from the datepicker
&lt;/h2&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;If I’m within the same component, getting the &lt;code&gt;startDate&lt;/code&gt; and &lt;code&gt;endDate&lt;/code&gt; are as simple as accessing the state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
 &amp;lt;div style={{ display: "flex" }}&amp;gt;
   &amp;lt;DatePicker ... /&amp;gt;
   &amp;lt;DatePicker ... /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div&amp;gt;Selected start date={startDate ? startDate.toString() : null}&amp;lt;/div&amp;gt;
 &amp;lt;div&amp;gt;Selected end date={endDate ? endDate.toString() : null}&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-11.png" alt="Retool-Use-React-datepicker-Example-11"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://reactjs.org/docs/lifting-state-up.html" rel="noopener noreferrer"&gt;React docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your datepicker component with &lt;code&gt;react-datepicker&lt;/code&gt;
&lt;/h2&gt;



&lt;p&gt;Here is our final datepicker:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F08%2FRetool-Use-React-datepicker-Example-10-1.gif" alt="Retool-Use-React-datepicker-Example-10-1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 (
   &amp;lt;div style={{ display: "flex" }}&amp;gt;
     &amp;lt;DatePicker
       isClearable
       filterDate={d =&amp;gt; {
         return new Date() &amp;gt; d;
       }}
       placeholderText="Select Start Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date =&amp;gt; setStartDate(date)}
     /&amp;gt;
     &amp;lt;DatePicker
       isClearable
       filterDate={d =&amp;gt; {
         return new Date() &amp;gt; d;
       }}
       placeholderText="Select End Date"
       showTimeSelect
       dateFormat="MMMM d, yyyy h:mmaa"
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date =&amp;gt; setEndDate(date)}
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 );
}

export default function TableDatePicker() {
 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;DatePickerRange /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more code samples that cover the vast range of features that &lt;code&gt;react-datepicker&lt;/code&gt; has to offer, check out &lt;a href="https://reactdatepicker.com/" rel="noopener noreferrer"&gt;React Datepicker’s website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For a full version of this code that you can test out and play around with, check out our &lt;a href="https://codesandbox.io/s/react-datepicker-ig3u9" rel="noopener noreferrer"&gt;code sandbox&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="tldr"&gt;TL;DR: Syntax roundup&lt;/h2&gt;



&lt;h3&gt;
  
  
  Create a simple datepicker
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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 (
   &amp;lt;DatePicker selected={date} onChange={date =&amp;gt; setDate(date)} /&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a datepicker range
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function TableDatePicker() {
 const [startDate, setStartDate] = useState(new Date());
 const [endDate, setEndDate] = useState(new Date());

 return (
   &amp;lt;div&amp;gt;
     &amp;lt;DatePicker
       selected={startDate}
       selectsStart
       startDate={startDate}
       endDate={endDate}
       onChange={date =&amp;gt; setStartDate(date)}
     /&amp;gt;
     &amp;lt;DatePicker
       selected={endDate}
       selectsEnd
       startDate={startDate}
       endDate={endDate}
       minDate={startDate}
       onChange={date =&amp;gt; setEndDate(date)}
     /&amp;gt;
   &amp;lt;/div&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Selecting time with datepicker
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 showTimeSelect
 dateFormat="MMMM d, yyyy h:mmaa"
 selected={date}
 onChange={date =&amp;gt; setDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add a placeholder
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function TableDatePicker() {
 const [date, setDate] = useState(null);

 return (
   &amp;lt;DatePicker
     placeholderText="Select Date"
     selected={date}
     onChange={date =&amp;gt; setDate(date)}
   /&amp;gt;
 );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disable future dates
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 filterDate={d =&amp;gt; {
   return new Date() &amp;gt; d;
 }}
 selected={date}
 onChange={date =&amp;gt; setDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add a clear button to the datepicker
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;DatePicker
 isClearable
 selected={date}
 onChange={date =&amp;gt; setDate(date)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building a React Table Component with react-table</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Tue, 18 Aug 2020 19:06:02 +0000</pubDate>
      <link>https://dev.to/retool/building-a-react-table-component-with-react-table-4d48</link>
      <guid>https://dev.to/retool/building-a-react-table-component-with-react-table-4d48</guid>
      <description>&lt;p&gt;If you’re building internal tools – admin panels, dashboards, CRMs, you name it – chances are you’re thinking about how to build a table component to display, edit, and manipulate data. And if you’re working in React, you (thankfully) don’t need to build it from scratch: the &lt;a href="https://github.com/tannerlinsley/react-table" rel="noopener noreferrer"&gt;react-table&lt;/a&gt; library gives you Hooks to get tables up and running quickly.  &lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you’ll know how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build a simple table with React&lt;/strong&gt; and modify data, columns, and headers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give your table a custom UI&lt;/strong&gt; by passing CSS into each component using &lt;code&gt;styled-components&lt;/code&gt; or piggybacking off a React component library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extend your table with more features&lt;/strong&gt; like sorting, filtering, and pagination.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learning all of these things yourself can be complicated. Thankfully, the react-table library is killer (and we made you this guide to help).&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro: react-table
&lt;/h2&gt;



&lt;p&gt;React-table is an open-source library specifically for building (you guessed it) tables in React. &lt;a href="https://github.com/tannerlinsley/react-table" rel="noopener noreferrer"&gt;The library has over 11.5k stars on GitHub&lt;/a&gt; and is used by tons of big-name tech companies, like Google, Apple, and Microsoft. Plus, we like it so much here at Retool that we sponsor it.&lt;/p&gt;

&lt;p&gt;We like react-table because it’s easy to set up, customize, and extend. The library covers the basics of a useful table — sorting, filtering, and pagination — but also goes much deeper with advanced features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grouping&lt;/li&gt;
&lt;li&gt;Expanded State&lt;/li&gt;
&lt;li&gt;Custom Plugin Hooks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It should be noted that react-table is a “&lt;a href="https://www.merrickchristensen.com/articles/headless-user-interface-components/" rel="noopener noreferrer"&gt;headless&lt;/a&gt;” UI library. The library doesn’t actually render a user interface. While this may sound strange, it was designed this way to give you more control over the look and feel of the react-table component while keeping the package size small. Don’t worry, adding UI is easy, and we will cover that later on. &lt;/p&gt;

&lt;p&gt;Since we’re all about internal tools, let’s imagine that we are building a table to display order information for customer service reps. Our table will need to display customer info (name and address) and order info (order number and date) for each customer’s purchase.&lt;/p&gt;

&lt;p&gt;When you’ve finished working through this tutorial, you will have five versions of a table built with react-table: simple, styled, sortable, filterable, and paged. Below is the final, paged version we’re aiming for.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0s0mAay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Pagination.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0s0mAay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Pagination.gif" alt="Retool-React-Table-Pagination" width="794" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It could look better, but that’s what CSS is for!&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a simple table with react-table
&lt;/h2&gt;



&lt;p&gt;First, we’ll build a basic table to display data, no styling or extra features. Our customer support reps need an easy way to view order information for each customer. Our simple table will have two top-level headers: &lt;strong&gt;User Info&lt;/strong&gt; and &lt;strong&gt;Order Info&lt;/strong&gt;. Under &lt;strong&gt;User Info&lt;/strong&gt;, we need two secondary headers to display each customer’s &lt;strong&gt;Name&lt;/strong&gt; and &lt;strong&gt;Address&lt;/strong&gt;. Under Order Info, we need two more secondary headers to display the &lt;strong&gt;Date&lt;/strong&gt; that the order was made and the &lt;strong&gt;Order Number&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this section, we’ll build a table with four columns split into two groups. We’ll break down how to define the shape of column objects and data, parse header groups, and fill out our rows and cells. At the end, expect to see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CpZFYav6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CpZFYav6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table.png" alt="Retool-React-Table" width="800" height="309"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Note that we did add a tiny bit of extra styling to this section, so the table has lines.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Taking care of housekeeping basics first, you’ll need to install react-table by using a package manager (Yarn or npm) and import the library into your React app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTable } from 'react-table';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, once react-table is installed and imported, it’s time to define our data and columns by way of the &lt;code&gt;useTable&lt;/code&gt; Hook. React-table leverages &lt;a href="https://reactjs.org/docs/hooks-overview.html" rel="noopener noreferrer"&gt;Hooks&lt;/a&gt;, which are a fairly new addition to React (as of version 16.8). If you’re not familiar with React Hooks, we recommend taking a look at React’s &lt;a href="https://reactjs.org/docs/hooks-overview.html" rel="noopener noreferrer"&gt;Hooks at a Glance&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;The most important Hook for our table is &lt;code&gt;useTable&lt;/code&gt;. We’ll pass two arguments to &lt;code&gt;useTable&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;data&lt;/strong&gt; = table data defined with the &lt;code&gt;useMemo&lt;/code&gt; Hook (data must be &lt;a href="https://reactjs.org/docs/hooks-reference.html#usememo" rel="noopener noreferrer"&gt;memo-ized&lt;/a&gt; before it can be passed to &lt;code&gt;useTable&lt;/code&gt; to cut down on calculation time by preventing unchanged data from being rerun)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = React.useMemo(() =&amp;gt;
 [
 {
 name: 'Kim Parrish',
 address: '4420 Valley Street, Garnerville, NY 10923',
 date: '07/11/2020',
 order: '87349585892118',
 },
 {
 name: 'Michele Castillo',
 address: '637 Kyle Street, Fullerton, NE 68638',
 date: '07/11/2020',
 order: '58418278790810',
 },
 {
 name: 'Eric Ferris',
 address: '906 Hart Country Lane, Toccoa, GA 30577',
 date: '07/10/2020',
 order: '81534454080477',
 },
 {
 name: 'Gloria Noble',
 address: '2403 Edgewood Avenue, Fresno, CA 93721',
 date: '07/09/2020',
 order: '20452221703743',
 },
 {
 name: 'Darren Daniels',
 address: '882 Hide A Way Road, Anaktuvuk Pass, AK 99721',
 date: '07/07/2020',
 order: '22906126785176',
 },
 {
 name: 'Ted McDonald',
 address: '796 Bryan Avenue, Minneapolis, MN 55406',
 date: '07/07/2020',
 order: '87574505851064',
 },
 ],
 []
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;columns&lt;/strong&gt; = column definitions defined with the &lt;code&gt;useMemo&lt;/code&gt; Hook (column defs must be memoized before they can be passed to &lt;code&gt;useTable&lt;/code&gt;)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const columns = React.useMemo(
 () =&amp;gt; [
 {
 Header: 'User Info',
 columns: [
 {
 Header: 'Name',
 accessor: 'name',
 },
 {
 Header: 'Address',
 accessor: 'address',
 },
 ],
 },
 {
 Header: 'Order Info',
 columns: [
 {
 Header: 'Date',
 accessor: 'date',
 },
 {
 Header: 'Order #',
 accessor: 'order',
 },
 ],
 },
 ],
 []
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a second to look at the relationship between &lt;strong&gt;data&lt;/strong&gt; and &lt;strong&gt;columns&lt;/strong&gt;. The &lt;code&gt;accessor&lt;/code&gt; in &lt;strong&gt;columns&lt;/strong&gt; is the “key” in the &lt;strong&gt;data&lt;/strong&gt; object. This is important to be able to access the right data for each column once we use &lt;code&gt;useTable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once we have defined &lt;strong&gt;data&lt;/strong&gt; and &lt;strong&gt;columns&lt;/strong&gt;, it’s time to implement our &lt;code&gt;useTable&lt;/code&gt; Hook. Pass &lt;strong&gt;data&lt;/strong&gt; and &lt;strong&gt;columns&lt;/strong&gt; into &lt;code&gt;useTable&lt;/code&gt;, which will return properties that we can extract to build our table UI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
 getTableProps,
 getTableBodyProps,
 headerGroups,
 rows,
 prepareRow,
} = useTable({ columns, data })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we’ll use these extracted properties to build out our table via familiar JSX tags –  &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt; – and then fill in our properties from &lt;code&gt;useTable&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Table
&lt;/h3&gt;

&lt;p&gt;First, we need &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; to wrap the rest of our code, and we need to pass the &lt;code&gt;getTableProps()&lt;/code&gt; function in to resolve any table props.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table {...getTableProps()}&amp;gt;
 ...
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Headers
&lt;/h3&gt;

&lt;p&gt;Things start to heat up a little bit when we start to build our headers! On a high level, all we are doing is creating our header rows using the column header names that we defined above. Before we jump into the code, let’s look at the rendered table to get a better idea:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4VuAVslU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool_headers_groups.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4VuAVslU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool_headers_groups.png" alt="Retool_headers_groups" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each circled section in the table above is a &lt;strong&gt;headerGroup&lt;/strong&gt;, which is simply an object that contains an array of &lt;strong&gt;headers&lt;/strong&gt; for that row. For this table, we will have two header rows: the header circled in red is the first headerGroup, and the header circled in blue is the second headerGroup.&lt;/p&gt;

&lt;p&gt;To get the data we need to build these headers out of headerGroups, we will be using JavaScript’s &lt;code&gt;map()&lt;/code&gt; method. If you’re unfamiliar with it, take a second to read the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, we have our &lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt; tag, which is simple enough. Inside of that tag, we are going to use &lt;code&gt;map()&lt;/code&gt; to parse each headerGroup, creating a new row using the &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt; and passing that headerGroup’s &lt;code&gt;getHeaderGroupProps()&lt;/code&gt; method in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{headerGroups.map(headerGroup =&amp;gt; (
   &amp;lt;tr {...headerGroup.getHeaderGroupProps()}&amp;gt;
     ...
   &amp;lt;/tr&amp;gt;
))}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside of the &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;, we use &lt;code&gt;map()&lt;/code&gt; again, but this time on the array of headers. Each header object has a &lt;code&gt;Header&lt;/code&gt; property (which is the name you’ll give each header), a &lt;code&gt;render()&lt;/code&gt; function, and another prop resolver function called &lt;code&gt;getHeaderProps()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;For each column, we use the &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt; tag to create the column, being sure to pass that column’s prop resolver function &lt;code&gt;getHeaderProps()&lt;/code&gt; and then use the &lt;code&gt;render()&lt;/code&gt; function to access the Header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;thead&amp;gt;
 {headerGroups.map(headerGroup =&amp;gt; (
   &amp;lt;tr {...headerGroup.getHeaderGroupProps()}&amp;gt;
     {headerGroup.headers.map(column =&amp;gt; (
       &amp;lt;th {...column.getHeaderProps()}&amp;gt;{column.render('Header')}&amp;lt;/th&amp;gt;
     ))}
   &amp;lt;/tr&amp;gt;
 ))}
&amp;lt;/thead&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Table Body
&lt;/h3&gt;

&lt;p&gt;Similar to how we did &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;, we add &lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt; and pass the prop resolver function &lt;code&gt;getTableBodyProps()&lt;/code&gt; in. Then, we use &lt;code&gt;map()&lt;/code&gt; to iterate through &lt;strong&gt;rows&lt;/strong&gt;, which is an array of &lt;strong&gt;Row&lt;/strong&gt; objects. Each &lt;strong&gt;Row&lt;/strong&gt; object has a &lt;strong&gt;cells&lt;/strong&gt; field, which is just an array of &lt;strong&gt;Cell&lt;/strong&gt; objects that contain the data for each cell in the row.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CqMEFyD6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Component-Table-Body.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CqMEFyD6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Component-Table-Body.png" alt="Retool-React-Table-Component-Table-Body" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The orange circle shows a row, and the pink circle shows a cell.&lt;/p&gt;

&lt;p&gt;For each row, we need to pass the row object to the &lt;code&gt;prepareRow()&lt;/code&gt; function, which helps with rendering efficiently. Next, we return &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt; tags to render the row. In each &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt;, we again use &lt;code&gt;map()&lt;/code&gt; to parse cells. For each cell, we create a &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; tag, pass in the prop resolver function &lt;code&gt;getCellProps()&lt;/code&gt;, and then render the cell data using the &lt;code&gt;render()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;tbody {...getTableBodyProps()}&amp;gt;
 {rows.map(row =&amp;gt; {
   prepareRow(row)
   return (
     &amp;lt;tr {...row.getRowProps()}&amp;gt;
       {row.cells.map(cell =&amp;gt; {
         return &amp;lt;td {...cell.getCellProps()}&amp;gt;{cell.render('Cell')}&amp;lt;/td&amp;gt;
       })}
     &amp;lt;/tr&amp;gt;
   )
 })}
&amp;lt;/tbody&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s put all of that together to render our table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
 &amp;lt;table {...getTableProps()}&amp;gt;
   &amp;lt;thead&amp;gt;
     {headerGroups.map(headerGroup =&amp;gt; (
       &amp;lt;tr {...headerGroup.getHeaderGroupProps()}&amp;gt;
         {headerGroup.headers.map(column =&amp;gt; (
           &amp;lt;th {...column.getHeaderProps()}&amp;gt;{column.render('Header')}&amp;lt;/th&amp;gt;
         ))}
       &amp;lt;/tr&amp;gt;
     ))}
   &amp;lt;/thead&amp;gt;
   &amp;lt;tbody {...getTableBodyProps()}&amp;gt;
     {rows.map(row =&amp;gt; {
       prepareRow(row)
       return (
         &amp;lt;tr {...row.getRowProps()}&amp;gt;
           {row.cells.map(cell =&amp;gt; {
             return &amp;lt;td {...cell.getCellProps()}&amp;gt;{cell.render('Cell')}&amp;lt;/td&amp;gt;
           })}
         &amp;lt;/tr&amp;gt;
       )
     })}
   &amp;lt;/tbody&amp;gt;
 &amp;lt;/table&amp;gt;
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the above code, you’ll end up with a rendered table that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ovlPkvF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Simple-React-Table-Final.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ovlPkvF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Simple-React-Table-Final.png" alt="Retool-Simple-React-Table-Final" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Give your table a custom UI
&lt;/h2&gt;



&lt;p&gt;Even if you’re building a tool that will only be used by an internal team, it’s still important for the UI to look good (or at least not terrible). Styling (at least the basics) is extra important with react-table too since no components are actually rendered as part of the library. Without any styling, you’ll end up with a table like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gnFiqmao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Simple-Unstyled-React-Table.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gnFiqmao--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Simple-Unstyled-React-Table.png" alt="Retool-Simple-Unstyled-React-Table" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can style your react-table component by either creating custom styles or through a React component library. The final product from this section will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lQkOUBa8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Styled.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lQkOUBa8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Styled.png" alt="Retool-React-Table-Styled" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn’t it beautiful?&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the &lt;code&gt;style&lt;/code&gt; Prop
&lt;/h3&gt;

&lt;p&gt;Styling your table with react-table is as simple as passing CSS into the &lt;code&gt;style&lt;/code&gt; prop of each component. Let’s look at the &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt; tag for styling a header row:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;th
 {...column.getHeaderProps()}
 style={{
   borderBottom: 'solid 3px blue',
   background: 'green',
   color: 'white',
   fontWeight: 'bold',
 }}
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use CSS files and CSS modules if you’d like. Check out React’s &lt;a href="https://www.w3schools.com/react/react_css.asp" rel="noopener noreferrer"&gt;CSS docs&lt;/a&gt; for more info.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;styled-components&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;styled-components&lt;/code&gt; is a &lt;a href="https://blog.logrocket.com/8-reasons-to-use-styled-components-cf3788f0bb4d/" rel="noopener noreferrer"&gt;nifty React library&lt;/a&gt; that lets you style React components with CSS directly inside of JS code (as opposed to external CSS files). Lately, it’s become a really popular way to handle component styling in React, so you might want to use it for your table.&lt;/p&gt;

&lt;p&gt;To use &lt;code&gt;styled-components&lt;/code&gt;, &lt;a href="https://github.com/styled-components/styled-components" rel="noopener noreferrer"&gt;install the library&lt;/a&gt; and import it into your project. Create a component &lt;code&gt;Styles&lt;/code&gt; that uses &lt;code&gt;styled&lt;/code&gt; from the &lt;code&gt;styled-components&lt;/code&gt; library to create a &lt;code&gt;div&lt;/code&gt; with the styles for your table in CSS. Move all of your code for creating the &lt;code&gt;Table&lt;/code&gt; component into its own function. Then, in your &lt;code&gt;App&lt;/code&gt; function (where your columns and data are defined), return &lt;code&gt;&amp;lt;Styles&amp;gt;&lt;/code&gt; with your &lt;code&gt;&amp;lt;Table&amp;gt;&lt;/code&gt; rendered inside. This will apply the styles from the &lt;code&gt;styled-components&lt;/code&gt; on to your table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import styled from 'styled-components'

/* Pssst this has the rest of the styling we've been using
to give our table borders and non-ugly spacing */

const Styles = styled.div`
 table {
   border-spacing: 0;
   border: 1px solid black;

   tr {
     :last-child {
       td {
         border-bottom: 0;
       }
     }
   }

   th,
   td {
     padding: 0.5rem;
     border-bottom: 1px solid black;
     border-right: 1px solid black;

     :last-child {
       border-right: 0;
     }
   }

   th {
     background: green;
     border-bottom: 3px solid blue;
     color: white;
     fontWeight: bold;
   }
 }
`

function Table({ columns, data }) {
 const {
   getTableProps,
   getTableBodyProps,
   headerGroups,
   rows,
   prepareRow,
 } = useTable({
   columns,
   data,
 })

 // Render the UI for your table
 return (
   &amp;lt;table {...getTableProps()} &amp;gt;
     ...
   &amp;lt;/table&amp;gt;
 )
}

function App() {
 const columns = React.useMemo(...)

 const data = React.useMemo(...)

 return (
   &amp;lt;Styles&amp;gt;
     &amp;lt;Table columns={columns} data={data} /&amp;gt;
   &amp;lt;/Styles&amp;gt;
 )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using a React Component Library
&lt;/h3&gt;

&lt;p&gt;If you don’t want to style things yourself, using a React component library is the way to go. For this example, we’re going to use the &lt;code&gt;material-ui&lt;/code&gt; library to create a nice table with react-table.&lt;/p&gt;

&lt;p&gt;Going off of the Cell styling example above, we simply have to import &lt;code&gt;TableCell&lt;/code&gt; from &lt;code&gt;@material-ui/core/TableCell&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import TableCell from '@material-ui/core/TableCell'
...
&amp;lt;TableCell {...cell.getCellProps()}&amp;gt;
   {cell.render('Cell')}
&amp;lt;/TableCell&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will bring all of the styling of the &lt;code&gt;TableCell&lt;/code&gt; component in &lt;code&gt;material-ui&lt;/code&gt;. No extra work for you!&lt;/p&gt;

&lt;p&gt;Click &lt;a href="https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/material-UI-components" rel="noopener noreferrer"&gt;here&lt;/a&gt; for a full sandbox version of this code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extend your table with more features
&lt;/h2&gt;



&lt;p&gt;No table worth rendering is going to have only two columns and three rows, like our example. Most likely, you're going to have a hefty portion of columns and row upon row of data. You'll need features to allow users to sift through all that data, like sorting, filtering, and pagination.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorting
&lt;/h3&gt;

&lt;p&gt;We want to give our customer service reps the ability to easily find what they are looking for, and sorting is a great way to accomplish that! If the reps want to see the most recent orders placed, they can sort by date from the &lt;strong&gt;Date&lt;/strong&gt; column. If they want to scan through the customers alphabetically, they can sort by name in the &lt;strong&gt;Name&lt;/strong&gt; column.&lt;/p&gt;

&lt;p&gt;Sorting is accomplished by using the &lt;code&gt;useSortBy&lt;/code&gt; Hook from react-table. Be sure to add that to your import statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTable, useSortBy } from 'react-table' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll need to pass &lt;code&gt;useSortBy&lt;/code&gt; into the &lt;code&gt;useTable&lt;/code&gt; Hook arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
 getTableProps,
 headerGroups,
 rows,
 getRowProps,
 prepareRow,
} = useTable(
 {
   columns,
   data,
 },
 useSortBy,
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want the sorting to be done by anything other than the default alphanumeric value, you’ll need to update your &lt;code&gt;columns&lt;/code&gt; definition with a &lt;code&gt;sortType&lt;/code&gt; field. Sorting options include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;alphanumeric&lt;/code&gt; = Best for sorting letters and numbers (default)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;basic&lt;/code&gt; = Best for sorting numbers between 0 and 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;datetime&lt;/code&gt; = Best for sorting by date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this example, we will be using the default, but if you needed to add that code, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const columns = React.useMemo(
 () =&amp;gt; [
   {
     Header: 'Rating',
     accessor: 'rating',
     sortType: 'basic',
   },
 ],
 []
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now there are two more things to do. First, pass the &lt;code&gt;getSortByToggleProps()&lt;/code&gt; function into your &lt;code&gt;getHeaderProps()&lt;/code&gt; function. The &lt;code&gt;getSortByToggleProps()&lt;/code&gt; function resolves props for toggling the sort direction when the user clicks on the header.&lt;/p&gt;

&lt;p&gt;Second, add a &lt;code&gt;span&lt;/code&gt; tag to display an arrow up, an arrow down, or nothing to the column header to indicate how that column is sorted. You can determine how the column is sorted by checking column properties &lt;code&gt;isSorted&lt;/code&gt; and &lt;code&gt;isSortedDesc&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;thead&amp;gt;
 {headerGroups.map(headerGroup =&amp;gt; (
   &amp;lt;tr {...headerGroup.getHeaderGroupProps()}&amp;gt;
     {headerGroup.headers.map(column =&amp;gt; (
       &amp;lt;th {...column.getHeaderProps(column.getSortByToggleProps())}&amp;gt;
         {column.render('Header')}
         &amp;lt;span&amp;gt;
           {column.isSorted ? (column.isSortedDesc ? ' 🔽' : ' 🔼') : ''}
         &amp;lt;/span&amp;gt;
       &amp;lt;/th&amp;gt;
     ))}
   &amp;lt;/tr&amp;gt;
 ))}
&amp;lt;/thead&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GgueJpdB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Styling-React-Table.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GgueJpdB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-Styling-React-Table.gif" alt="Retool-Styling-React-Table" width="782" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out this &lt;a href="https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/sorting?file=/src/App.js:1275-1337" rel="noopener noreferrer"&gt;code sandbox&lt;/a&gt; for a more advanced version of sorting using react-table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Filtering
&lt;/h3&gt;

&lt;p&gt;For the sake of simplicity, this tutorial is going to focus on how to add a text filter on the columns of our simple table. This will give our customer support reps the ability to quickly find the information they are looking for. If a customer contacts them, the rep can easily search the &lt;strong&gt;Names&lt;/strong&gt; column for that customer to find their orders or search the &lt;strong&gt;Order Numbers&lt;/strong&gt; column to look up a specific order.&lt;/p&gt;

&lt;p&gt;For further examples of all the different kinds of filters (including global, which is really useful), check out this the &lt;a href="https://react-table.tanstack.com/docs/api/useFilters" rel="noopener noreferrer"&gt;react-table docs&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Filtering is accomplished by using the &lt;code&gt;useFilters()&lt;/code&gt; Hook from react-table. Be sure to add that to your import statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTable, useFilters } from 'react-table' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll need to pass &lt;code&gt;useFilters&lt;/code&gt; into the &lt;code&gt;useTable&lt;/code&gt; Hook arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
 getTableProps,
 headerGroups,
 rows,
 getRowProps,
 prepareRow,
} = useTable(
 {
   columns,
   data,
 },
 useFilters,
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we are going to add the UI for the column filter into our table. If there is a filter applied to this column, we render the UI for the filter by calling the column’s &lt;code&gt;render()&lt;/code&gt; method on the Filter field. Otherwise, do nothing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;th {...column.getHeaderProps()}&amp;gt;
 {column.render('Header')}
 &amp;lt;div&amp;gt;{column.canFilter ? column.render('Filter') : null}&amp;lt;/div&amp;gt;
&amp;lt;/th&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait! We haven’t defined the UI for the filter yet. We’ll need a function to do that – for our filter function, we first want to find out how many rows are left to be filtered, so we can display that number to the user as an input placeholder. Then, we will render an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; for the user to type what they want to filter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function TextFilter({
 column: { filterValue, preFilteredRows, setFilter },
}) {
 const count = preFilteredRows.length
 return (
   &amp;lt;input
     value={filterValue || ''}
     onChange={e =&amp;gt; {
       setFilter(e.target.value || undefined)
     }}
     placeholder={`Search ${count} records...`}
   /&amp;gt;
 )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;TextFilter()&lt;/code&gt; function receives three values from &lt;strong&gt;column&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;filterValue&lt;/strong&gt; = the current value that this &lt;strong&gt;column&lt;/strong&gt; is using to filter.

&lt;ul&gt;
&lt;li&gt;This value is set from the table’s state &lt;strong&gt;filters&lt;/strong&gt; object.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;preFilteredRows&lt;/strong&gt; = Array of rows passed to the column before any filtering was done.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;setFilter&lt;/strong&gt; = function that takes in a &lt;strong&gt;filterValue&lt;/strong&gt; in order to update the filterValue of this column (in this case, it’s taking the value that the user types into the

&lt;p&gt;&lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;).&lt;/p&gt;
&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Once we’ve defined our filter function, we’ll update the definition of our column object to have a &lt;code&gt;Filter&lt;/code&gt; field. Add this code to your Table function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const defaultColumn = React.useMemo(
 () =&amp;gt; ({
   Filter: TextFilter,
 }),
 []
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, make sure to pass &lt;code&gt;defaultColumn&lt;/code&gt; in with the columns and data arguments when you use &lt;code&gt;useTable()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
 getTableProps,
 ...
} = useTable(
 {
   columns,
   data,
   defaultColumn,
 },
 useFilters,
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cpfqKFfo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Filtering.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cpfqKFfo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Filtering.gif" alt="Retool-React-Table-Filtering" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pagination
&lt;/h3&gt;

&lt;p&gt;The data we created for the example in this tutorial is pretty small compared to what you would see in the real world. Only six rows? Please. In reality, our customer support reps would be dealing with hundreds (maybe even thousands) of rows of customer data. To avoid long render times and ginormous pages to scroll through, we are going to add pagination to our table. This will allow react-table to only deal with rendering some rows at a time and will take some strain off the customer support reps from having to look at overwhelming amounts of data.&lt;/p&gt;

&lt;p&gt;Pagination is accomplished by using the &lt;code&gt;usePagination()&lt;/code&gt; Hook from react-table. Be sure to add that to your import statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useTable, usePagination } from 'react-table' 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll need to pass &lt;code&gt;usePagination()&lt;/code&gt; into the &lt;code&gt;useTable()&lt;/code&gt; Hook arguments, set the initial state (if you want to start the &lt;code&gt;pageIndex&lt;/code&gt; at anything other than 0 or have the &lt;code&gt;pageSize&lt;/code&gt; bigger or smaller than 10), and extract extra properties from what it returns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {
   getTableProps,
   headerGroups,
   getRowProps,
   prepareRow,
   page,
   pageOptions,
   state: { pageIndex, pageSize },
   previousPage,
   nextPage,
   canPreviousPage,
   canNextPage,
 } = useTable(
   {
     columns,
     data,
     initialState: { pageSize: 2 },
   },
   usePagination,
 )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that as well as iterating through &lt;code&gt;rows&lt;/code&gt; in &lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt; as we did previously before pagination, we are going to iterate through &lt;code&gt;page&lt;/code&gt;, which is similar to &lt;code&gt;rows&lt;/code&gt; except it only has the number of rows that fit on the page. If you don’t do this, you can click those buttons as much as you want — the data won’t move. Trust me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;tbody {...getTableBodyProps()}&amp;gt;
 {page.map(row =&amp;gt; {
   prepareRow(row)
   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have a button to go to the Previous Page, a button to go to the Next Page, and an input that lets the user type a page number to jump to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
   &amp;lt;div&amp;gt;
     &amp;lt;table {...getTableProps()}&amp;gt;
       ...
     &amp;lt;/table&amp;gt;
     &amp;lt;div&amp;gt;
       &amp;lt;button onClick={() =&amp;gt; previousPage()} disabled={!canPreviousPage}&amp;gt;
         Previous Page
       &amp;lt;/button&amp;gt;
       &amp;lt;button onClick={() =&amp;gt; nextPage()} disabled={!canNextPage}&amp;gt;
         Next Page
       &amp;lt;/button&amp;gt;
       &amp;lt;div&amp;gt;
         Page{' '}
         &amp;lt;em&amp;gt;
           {pageIndex + 1} of {pageOptions.length}
         &amp;lt;/em&amp;gt;
       &amp;lt;/div&amp;gt;
     &amp;lt;/div&amp;gt;
   &amp;lt;/div&amp;gt;
 )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0s0mAay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Pagination.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0s0mAay--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://retool.com/blog/content/images/2020/07/Retool-React-Table-Pagination.gif" alt="Retool-React-Table-Pagination" width="794" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out this &lt;a href="https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/pagination" rel="noopener noreferrer"&gt;code sandbox&lt;/a&gt; for a more advanced version of pagination using react-table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Table Component with react-table
&lt;/h2&gt;



&lt;p&gt;Hopefully, this tutorial helps you understand how to create, style, and extend a table in React using react-table. For more advanced tutorials, we recommend checking out the “&lt;a href="https://github.com/tannerlinsley/react-table/tree/master/examples/kitchen-sink" rel="noopener noreferrer"&gt;Kitchen Sink&lt;/a&gt;” example from react-table’s docs. It has fully fleshed-out examples of most things that react-table has to offer, from pagination and sorting to filtering, grouping, expandable rows, and row selection.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What's an ACID compliant database?</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Thu, 09 Apr 2020 20:09:12 +0000</pubDate>
      <link>https://dev.to/retool/what-s-an-acid-compliant-database-2j35</link>
      <guid>https://dev.to/retool/what-s-an-acid-compliant-database-2j35</guid>
      <description>&lt;p&gt;When you’re building and maintaining an application, &lt;strong&gt;the last thing you want to worry about is data integrity&lt;/strong&gt;; Charging a customer the wrong amount or losing their data can be catastrophic.  Thankfully, the databases you’re using — like MySQL and Postgres — take special measures to make sure that doesn’t happen. But what’s going on behind the hood? Most modern SQL DBs use transactional standards like ACID to ensure data integrity and keep your users from seeing wrong or stale data, and this post explores how they work.&lt;/p&gt;

&lt;h2&gt;
  
  
  All the things that can go wrong with your transactions
&lt;/h2&gt;




&lt;p&gt;Data Scientists worry about long analytical queries and warehousing, but for developers, databases are all about transactions. A database transaction is a series of logically grouped database operations: insert a row here, update a record there, and more stuff like that. Your application code is constantly making transactions every time you sign up a new user or that user updates their account information. &lt;/p&gt;

&lt;p&gt;The thing about transactions, though, is that they can go very wrong. Any number of things can happen when you’re trying to write to your database: you can lose connection to a remote instance, you can encounter value errors, or anything else under the sun. You’ve seen it, you’ve dealt with it, and it can mean disaster for your underlying data. Let’s take a look at a quick example that a company like Amazon might run into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- User updates order quantity and clicks “order now” →
- Update order quantity in the pending orders table
- Add row to orders table
- Apply the purchase to user’s balance / charge credit card
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something goes wrong in the middle of this group of operations but the system continues executing them, the user will get charged the wrong amount. And if the charge doesn’t work, they’ll get their order for free. It turns out that &lt;a href="https://vladmihalcea.com/a-beginners-guide-to-acid-and-database-transactions/" rel="noopener noreferrer"&gt;these kinds of data errors have names&lt;/a&gt;, and there are a bunch of them. A few examples:&lt;/p&gt;

&lt;h3&gt;
  
  
  Dirty Reads
&lt;/h3&gt;



&lt;p&gt;If a transaction is in the middle of updating some data and hasn’t committed yet, and another transaction is allowed to read that uncommitted data, that’s dirty, and could lead to your app showing incorrect data that got rolled back.&lt;/p&gt;

&lt;p&gt;An example of a dirty read could be a transaction that invalidates login tokens when a user changes their password. If as the first transaction loads the token, a second one reads that token before the first invalidates it, you’d have yourself a dirty read.&lt;/p&gt;

&lt;p&gt;In terms of actual SQL, here's what a dirty read might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_login_token_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;token_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"INVALID"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;token_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_login_token_id&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_login_token_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Non-Repeatable Reads
&lt;/h3&gt;



&lt;p&gt;If you’ve got two consecutive reads in one transaction with a concurrent update in between, those reads are going to show different results even though they’re part of the same transaction.&lt;/p&gt;

&lt;p&gt;An example might be two writers working on a blog. Our first user starts a transaction that reads a post’s title, writes to the post, and then reads that post’s title again. If a second user changes that post’s title in the middle of the first user’s transaction, the first user is going to see different values for the title across the two reads; or in other words, a non-repeatable read.&lt;/p&gt;

&lt;p&gt;Here's what a non-repeatable read might look like in SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;post_content&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"something_new"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phantom Reads
&lt;/h3&gt;



&lt;p&gt;If a transaction reads data and then a concurrent transaction inserts data that would have been read in the original transaction, that’s a phantom read. &lt;/p&gt;

&lt;p&gt;Let’s use the same example as a non-repeatable read: if our second user adds content in between our first user’s two reads, the first read will be missing data that appears in the second read (this is actually really similar to a non-repeatable read, which is why the same example works).&lt;/p&gt;

&lt;p&gt;In SQL, a phantom read might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;post_content&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="nv"&gt;"something_new"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the 3 transactional errors &lt;a href="https://en.wikipedia.org/wiki/Isolation_(database_systems)#Read_phenomena" rel="noopener noreferrer"&gt;as defined by the SQL standard&lt;/a&gt; — the big three, you might say. A lot of these errors sound like one another and tend to overlap in practice, so don’t sweat the details. For more detailed information, check out &lt;a href="https://vladmihalcea.com/a-beginners-guide-to-acid-and-database-transactions/" rel="noopener noreferrer"&gt;Vlad Mihalcea’s blog series on the topic&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Now, the important question: how do we avoid these? &lt;/p&gt;

&lt;h2&gt;
  
  
  ACID, but the good kind
&lt;/h2&gt;




&lt;p&gt;Popular relational databases like MySQL avoid these kinds of data integrity issues by following a few core principles that govern how transactions work. They conform to a transactional standard called ACID. ACID is an acronym for four different words, but it really breaks down into two core principles: completeness and concurrency. First, here’s what ACID stands for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atomicity&lt;/strong&gt;: the “all or nothing” rule — the transaction either happens completely or doesn’t happen at all&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: data is consistent before and after a transaction without any missing steps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: multiple transactions can happen concurrently without reading the wrong data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durability&lt;/strong&gt;: transactional success is robust to system failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These overlap a lot, so just remember: the point of any ACID compliant DB is to make sure that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transactions can fail without hurting data integrity&lt;/li&gt;
&lt;li&gt;Multiple transactions can occur concurrently without reading and writing the wrong data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ACID is a set of properties, but it’s not a process: how do the SQL databases we use actually achieve ACID compliance? They use a system called locking to keep the database on hold while transactions happen. Locking works like you’d imagine it would: when a transaction begins, the database engine locks the data that it’s working with until the transaction is completed (and sometimes, beyond that). That way, concurrent transactions can’t work with the data that’s being changed by the first transaction.&lt;/p&gt;

&lt;p&gt;Once a transaction begins and acquires a lock, it can either finish successfully and commit, or run into an error and abort. It’s sort of like writing in an Excel spreadsheet before saving your work — things are changed, but only softly, until you save them (commit) or revert them (abort). Back to our Amazon example: if our database runs into an error right after updating a user’s order quantity, the transaction will abort, and it’s as if that update never happened. And if the error happened during the update, the credit card will never get charged. Either everything happens or nothing happens, and that’s ACID.&lt;/p&gt;

&lt;p&gt;The intricacies of commiting and locks are pretty hairy, but a good start is &lt;a href="https://www.methodsandtools.com/archive/archive.php?id=83" rel="noopener noreferrer"&gt;Methods and Tools’ excellent paper&lt;/a&gt; on the topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  ACID concepts in NoSQL and distributed systems
&lt;/h2&gt;




&lt;p&gt;ACID was a building block of the reliable relational DBs we’re familiar with today, but NoSQL has changed the game: many NoSQL DBs are built as distributed systems, and they can’t always ensure complete transactional consistency. There’s actually a theory that governs this — called &lt;a href="https://towardsdatascience.com/cap-theorem-and-distributed-database-management-systems-5c2be977950e" rel="noopener noreferrer"&gt;CAP theorem&lt;/a&gt; — that in distributed systems, you can’t never have full consistency and full availability; you need to choose one. So what does ACID look like for something like MongoDB or Cassandra?&lt;/p&gt;

&lt;p&gt;A new quasi-standard has emerged for NoSQL databases called BASE (a rare overlap between SQL and chemistry jokes), and it’s a weak or soft consistency model that &lt;a href="https://neo4j.com/blog/acid-vs-base-consistency-models-explained/" rel="noopener noreferrer"&gt;relaxes some of the assumptions of ACID&lt;/a&gt; in order to achieve scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic Availability&lt;/strong&gt;: the database basically works most of the time, even though it’s not perfect&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft-State&lt;/strong&gt;: nodes of the database aren’t necessarily consistent with each other all the time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eventual Consistency&lt;/strong&gt;: data will be consistent across nodes eventually, like by read time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a lot of ways, this is the exact opposite of ACID, and prioritizes availability over perfect consistency; but that’s kind of the point of NoSQL in the first place. As NoSQL becomes a more established part of app development (&lt;a href="https://insights.stackoverflow.com/survey/2019" rel="noopener noreferrer"&gt;more than 25% of developers&lt;/a&gt; are using MongoDB already), expect more advancements on this front.&lt;/p&gt;

&lt;p&gt;Today, we’re dealing with more data than we ever have, and we’re building database systems that can scale and handle that load. ACID might not be the exact transactional standard for the future, but its building blocks will certainly make their way in there.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Isolation levels and locking in relational databases</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Wed, 25 Mar 2020 17:04:06 +0000</pubDate>
      <link>https://dev.to/retool/isolation-levels-and-locking-in-relational-databases-1ca6</link>
      <guid>https://dev.to/retool/isolation-levels-and-locking-in-relational-databases-1ca6</guid>
      <description>&lt;p&gt;&lt;em&gt;“We need to build this for scale!” yells your manager, in a fury. You think back to a simpler time: when your application only had a few users. When your transactions executed sequentially, and you didn’t need to deal with things like Hot Locks and stalemates. Time to hire a DBA.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Running a database would be easy if your app only had one user, or if your users did one thing after another, never concurrently and never in contention. In reality though, you want to get more people using what you’ve built – your business needs to grow. Increased user volume tends to mean a lot of concurrent transactions, and all those requests bring us into the realm of database locking and isolation, a topic with little publicly available information (until you know what to search for!) and an almost mystic air to it. This post will hopefully make things simpler. &lt;/p&gt;

&lt;h2&gt;
  
  
  Why database locking and isolation exist
&lt;/h2&gt;



&lt;p&gt;A modern web application might need to handle hundreds of thousands of transactions daily, and the biggest ones deal with orders of magnitude more than that. That kind of scale can create a bunch of problems with data integrity, starting with the big 3 as defined by the SQL standard:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dirty Reads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a transaction is in the middle of updating some data and hasn’t committed yet, and another transaction is allowed to &lt;em&gt;read&lt;/em&gt; that uncommitted data, that’s called a dirty read, and could lead to your app showing incorrect data that got rolled back.&lt;/p&gt;

&lt;p&gt;An example of a dirty read could be a transaction that invalidates login tokens when a user changes their password. If as the first transaction loads the token, a second one reads that token before the first invalidates it, you’d have yourself a dirty read. &lt;/p&gt;

&lt;p&gt;In terms of actual SQL, here's what a dirty read might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_login_token_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;token_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"INVALID"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_login_token_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the second &lt;code&gt;SELECT&lt;/code&gt; statement was allowed to read the &lt;code&gt;user_login_token_id&lt;/code&gt; before the first transaction invalidated it, the read would be dirty: it's reading stale data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-Repeatable Reads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’ve got two consecutive reads in one transaction with a concurrent update in between, those reads are going to show different results even though they’re part of the same transaction.&lt;/p&gt;

&lt;p&gt;An example might be two writers working on a blog. Our first user starts a transaction that reads a post’s title, writes to the post, and then reads that post’s title again. If a second user changes that post’s title in the middle of the first user’s transaction, the first user is going to see different values for the title across the two reads; or in other words, a non-repeatable read.&lt;/p&gt;

&lt;p&gt;Here's what a non-repeatable read might look like in SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;post_content&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;"something_new"&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Phantom Reads&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a transaction reads data and then a concurrent transaction &lt;em&gt;inserts&lt;/em&gt; data that would have been read in the original transaction, that’s a phantom read. &lt;/p&gt;

&lt;p&gt;Let’s use the same example as a non-repeatable read: if our second user &lt;em&gt;adds&lt;/em&gt; content in between our first user’s two reads, the first read will be missing data that appears in the second read (this is actually really similar to a non-repeatable read, which is why the same example works).&lt;/p&gt;

&lt;p&gt;In SQL, a phantom read might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;post_title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;post_title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;post_content&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;

&lt;span class="o"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Transaction&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;###&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;posts&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="nv"&gt;"something_new"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To avoid all of this nastiness, most SQL databases follow a set of principles called ACID that prioritizes transactional integrity. We wrote all about ACID and concurrency in databases here, but the TL;DR is that databases use &lt;strong&gt;locks&lt;/strong&gt; that prevent data from being read or changed while a transaction is making use of it. &lt;/p&gt;

&lt;h2&gt;
  
  
  How database locking works
&lt;/h2&gt;

&lt;p&gt;So you’ve got your database — let’s say it’s a Postgres database — up and running, and you start a transaction. How does locking actually happen? Let’s take a look at two concurrent transactions and see how locking impacts them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Transaction 1 (T1) wants to read a user’s password and change it to a new one (&lt;code&gt;SELECT&lt;/code&gt; and &lt;code&gt;UPDATE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;  Transaction 2 (T2) wants to read that user’s password (&lt;code&gt;SELECT&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of the leftmost column as a time axis. When a transaction acquires a lock, other transactions basically won’t be able to interact with the locked data. Here’s how these concurrent transactions will play together:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Time&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 1&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 2&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;1
   &lt;/td&gt;
   &lt;td&gt;Selects row #1, and &lt;em&gt;acquires a lock on row #1&lt;/em&gt;
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Tries to select row #1, but blocked by T1’s lock
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3
   &lt;/td&gt;
   &lt;td&gt;Updates row #1 and commits transaction
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;4
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Selects row #1
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice that Transaction 1 is made up of two queries — a &lt;code&gt;SELECT&lt;/code&gt; and an &lt;code&gt;UPDATE&lt;/code&gt; — and even though the lock is &lt;em&gt;acquired&lt;/em&gt; on that first query, it _remains _until the end of the entire transaction when the transaction gets committed.&lt;/p&gt;

&lt;p&gt;The most common lock is on the &lt;strong&gt;row level&lt;/strong&gt;, like in our example; but locks are maintained in database memory, so having too many of them active at any point can be computationally prohibitive. This means if your DBMS (database management system) is running out of memory, it might &lt;strong&gt;escalate a lock&lt;/strong&gt; to a higher level to free up space. For example, if one database table has 40 different locks active on 40 different rows, the DBMS might escalate the lock to the table level so it can continue blocking while using less memory.&lt;/p&gt;

&lt;p&gt;Locks can exist across larger sections of your data, and even on an entire database. System level updates might acquire a &lt;em&gt;database lock&lt;/em&gt;, which would block &lt;em&gt;all&lt;/em&gt; transactions on any part of a database. That kind of lock is pretty uncommon, but table level locks are used pretty often (like our escalation example above), and page or file locks (this means different things across different database setups) are also not infrequent. &lt;/p&gt;

&lt;h2&gt;
  
  
  Levels of database isolation
&lt;/h2&gt;

&lt;p&gt;We’ve been assuming that a lock means that no other transactions can use the locked data &lt;em&gt;at all&lt;/em&gt;. But that’s not entirely true; in fact, if it was, your database would basically never work at even low levels of concurrency. Databases deal in different &lt;strong&gt;isolation levels&lt;/strong&gt; to help avoid lock craziness, and there are four (4) major ones:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;READ_UNCOMMITTED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the lowest level of isolation, and does almost nothing. It means that transactions can read data being worked with by other transactions, even if the changes aren’t committed yet. &lt;code&gt;READ_UNCOMMITTED&lt;/code&gt; doesn’t avoid &lt;em&gt;any&lt;/em&gt; of the three read problems that we outlined above. Let’s go back to our two transaction example and see what would happen:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Time&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 1&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 2&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;1
   &lt;/td&gt;
   &lt;td&gt;Selects row #1
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Selects row #1 (even though it’s currently being used by T1) 
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3
   &lt;/td&gt;
   &lt;td&gt;Updates row #1 and commits transaction
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Transaction 1 never acquires a lock when it starts, so Transaction 2 is able to slide in there and execute its &lt;code&gt;SELECT&lt;/code&gt; query. In this example, things turned out fine: but if T2 did its &lt;code&gt;SELECT&lt;/code&gt; query &lt;em&gt;after&lt;/em&gt; the update from T1, but T1 got rolled back (aborted), we’d have a dirty read on our hands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;READ_COMMITTED&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next level of isolation is &lt;code&gt;READ_COMMITTED&lt;/code&gt;, which adds a little locking into the equation to avoid dirty reads. In &lt;code&gt;READ_COMMITTED&lt;/code&gt;, transactions can only read data once writes have been committed. Let’s use our two transactions, but change up the order a bit: T2 is going to read data &lt;em&gt;after&lt;/em&gt; T1 has written to it, but then T1 gets rolled back (for some reason). &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Time&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 1&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 2&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;1
   &lt;/td&gt;
   &lt;td&gt;Selects row #1
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2
   &lt;/td&gt;
   &lt;td&gt;Updates row #1, acquires lock
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Tries to select row #1, but blocked by T1’s lock
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;4
   &lt;/td&gt;
   &lt;td&gt;Rolls back transaction
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;5
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Selects row #1
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;READ_COMMITTED&lt;/code&gt; helps avoid a dirty read here: if T2 was allowed to read row #1 at Time 3, that read would be invalid; T1 ended up getting rolled back, so the data that T2 read was actually wrong. Because of the lock acquired at Time 2 (thanks &lt;code&gt;READ_COMMITTED&lt;/code&gt;!), everything works smoothly and T2 waits to execute its SELECT query. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REPEATABLE_READ&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The most popular isolation level is &lt;code&gt;REPEATABLE_READ&lt;/code&gt;, which (surprise!) helps avoid non-repeatable reads. This iso level locks data from the start of the entire &lt;em&gt;transaction&lt;/em&gt; – including on &lt;code&gt;SELECT&lt;/code&gt; queries – as opposed to the start of the &lt;em&gt;query&lt;/em&gt;, which adds an additional layer of isolation.   &lt;/p&gt;

&lt;p&gt;If you recall from above, a non-repeatable read happens when one transaction has two &lt;code&gt;SELECT&lt;/code&gt; queries, and another transaction is able to insert or update a row that makes those two &lt;code&gt;SELECT&lt;/code&gt; queries show different results. &lt;code&gt;REPEATABLE_READ&lt;/code&gt; isolation avoids that by letting the first transaction acquire a lock when it starts the first &lt;code&gt;SELECT&lt;/code&gt; query:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Time&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 1&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 2&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;1
   &lt;/td&gt;
   &lt;td&gt;Selects row #1, acquires lock on row #1
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Tries to update row #1, but is blocked by T1’s lock
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3
   &lt;/td&gt;
   &lt;td&gt;Selects row #1, commits transaction
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;4
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Updates row #1
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you’re really clever, you might notice that &lt;code&gt;REPEATABLE_READ&lt;/code&gt; still doesn’t solve for phantom reads: Transaction 1 only acquired a lock on the row it was working with (Row #1), so Transaction 2 is still able to &lt;em&gt;insert&lt;/em&gt; a row that might show up in T1’s second &lt;code&gt;SELECT&lt;/code&gt; query. The only way to avoid that is with a higher lock level than a row, which is our next level of isolation. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SERIALIZABLE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the highest possible level of isolation, and is a bit difficult to define: in &lt;em&gt;practice&lt;/em&gt;, &lt;code&gt;SERIALIZABLE&lt;/code&gt; means that from the user’s perspective, transactions &lt;em&gt;appear&lt;/em&gt; as if they’re executing sequentially, not concurrently. In other words, isolation is &lt;em&gt;so intense&lt;/em&gt; that transactions will only execute concurrently if the end result is the same as them executing sequentially.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SERIALIZABLE&lt;/code&gt; also uses range locks to avoid phantom reads. Range locks are a mechanism that’s in between locking a row and locking a table: if you’re running a &lt;code&gt;SELECT&lt;/code&gt; query with a &lt;code&gt;WHERE&lt;/code&gt; clause, range locks will lock some of the rows that exist &lt;em&gt;close&lt;/em&gt; to your selected rows (before and after). &lt;/p&gt;

&lt;p&gt;Wikipedia has a pretty great summary chart for wrapping up how these isolation levels help avoid the SQL standard read problems:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F03%2FImage-2020-01-21-at-5.48.02-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fretool.com%2Fblog%2Fcontent%2Fimages%2F2020%2F03%2FImage-2020-01-21-at-5.48.02-PM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can think of isolation levels as lock settings: they determine when locks get acquired and released, and how intense that process is. Most modern SQL databases use &lt;code&gt;REPEATABLE_READ&lt;/code&gt; as the default isolation level, but it’s a setting that you can change internally if you need (even on a transaction level).&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems you’ll run into with database locks
&lt;/h2&gt;



&lt;p&gt;If you’ve been following along, you’ve probably gathered that locks solve a lot of problems, but they also block data access; and that might not always work out well for your application’s user. There are three big ones to worry about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lock Contention&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a bunch of user sessions all require access to the same lock concurrently, they’re not going to be able to retrieve the data they need. A good example here is anything that gets &lt;em&gt;incremented on activity&lt;/em&gt;, like a total monthly orders count in a metrics table. If every user order needs to increment that row, the constant locking is going to block your user requests. The cool kids also call this one a Hot Lock.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long Term Blocking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Long term lock issues happen when you have some sort of transaction or job that requires a lock for a long period of time. If you’re running a batch job that needs locking access to a table or row for a while (think: 15 minutes), and that table or row is also heavily used by smaller transactions, they’re going to get stuck waiting while the job finishes.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Deadlocks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A deadlock happens when two transactions both need to wait for each other to commit...to commit. This might sound kind of funky, so let’s use our classic two transaction example and see what can go wrong:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Time&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 1&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Transaction 2&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;1
   &lt;/td&gt;
   &lt;td&gt;Selects row #1, acquires lock on row #1
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;2
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Selects row #2, acquires lock on row #2
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;3
   &lt;/td&gt;
   &lt;td&gt;Tries to select row #2, blocked by T2’s lock
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;4
   &lt;/td&gt;
   &lt;td&gt;
   &lt;/td&gt;
   &lt;td&gt;Tries to select row #1, blocked by T1
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Your DBMS will usually resolve this stalemate by rolling back whichever transaction is easiest to roll back, but this is also a setting you can tweak when configuring your database. Methods and Tools wrote &lt;a href="https://www.methodsandtools.com/archive/archive.php?id=83" rel="noopener noreferrer"&gt;a great paper about this entire “locking issues” topic&lt;/a&gt; and how it impacts QA if you want to go deeper.&lt;/p&gt;




&lt;p&gt;If you’re building your app on top of a SQL database, &lt;strong&gt;check out &lt;a href="https://retool.com" rel="noopener noreferrer"&gt;Retool&lt;/a&gt;&lt;/strong&gt;! Retool saves you a bunch of time and hassle by letting you drag and drop components like tables, search boxes, and buttons, and connecting them to SQL or Javascript on the backend. Retool also protects you against bad writes (no accidental DROP TABLE;) through a GUI based write interface.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Formatting and dealing with dates in SQL</title>
      <dc:creator>justin gage</dc:creator>
      <pubDate>Wed, 04 Mar 2020 21:29:41 +0000</pubDate>
      <link>https://dev.to/retool/formatting-and-dealing-with-dates-in-sql-5hmh</link>
      <guid>https://dev.to/retool/formatting-and-dealing-with-dates-in-sql-5hmh</guid>
      <description>&lt;p&gt;&lt;strong&gt;It’s 3AM, and you’re sleeping soundly in your room&lt;/strong&gt;. But slowly, your sweet dream turns into a nightmare: all of the queries you wrote earlier in the day are parsing dates wrong, your app is down, and your boss is angry. It turns out migrating from Redshift to Bigquery was not “as easy as 123” and your DBA switched all of your timestamps to unix time. Nice.&lt;/p&gt;

&lt;p&gt;Nobody likes dates, especially programmers, but they’re a critical part of pretty much every application. In Javascript you’ve got Moment, but parsing dates in SQL is a bit more complex. This post will run through how you can effectively work with dates in SQL, resolve your issue quickly, and get back to bed.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL dialects and function prototypes
&lt;/h2&gt;




&lt;p&gt;Part of why writing SQL is annoying is that there are hundreds of different flavors. Syntax is slightly different from MySQL to PostgreSQL (for example), and some dialects have functions that others don’t (e.g. &lt;code&gt;PIVOT&lt;/code&gt; in Snowflake). When you’re working with dates, there are prototypes for types of functions: even though the exact syntax might differ between dialects, the idea is the same. We’ll tackle 5 broad categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Formatting&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time differences / deltas&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intervals&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Time zones&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Current times&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each function prototype, we’ll provide the right syntax and documentation for 5 of the more popular SQL dialects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.mysql.com/" rel="noopener noreferrer"&gt;MySQL&lt;/a&gt; – the world’s most popular open source relational database (thanks, Oracle)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; – the world’s second most popular open source relational database, and a developer favorite for syntax&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com/bigquery/" rel="noopener noreferrer"&gt;BigQuery&lt;/a&gt; – Google’s cloud based data warehouse that shares SQL syntax with other GCP databases (Standard SQL)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aws.amazon.com/redshift/" rel="noopener noreferrer"&gt;Redshift&lt;/a&gt; – Amazon’s cloud based data warehouse (or at least one of them) &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://prestodb.io/" rel="noopener noreferrer"&gt;Presto&lt;/a&gt; – a popular open source query engine built by Facebook and often used with HDFS / Hive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Something that often gets confusing is the difference between &lt;code&gt;DATE&lt;/code&gt; and &lt;code&gt;TIMESTAMP&lt;/code&gt;. A &lt;code&gt;TIMESTAMP&lt;/code&gt; is just a &lt;code&gt;DATE&lt;/code&gt; with an additional two levels of precision: fractional seconds and fractional seconds with time zones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nb"&gt;DATE&lt;/span&gt;
&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt; &lt;span class="n"&gt;PM&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;
&lt;span class="mi"&gt;2019&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;000148&lt;/span&gt; &lt;span class="n"&gt;PM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In general, we’ll use “date” in this tutorial but the distinction isn’t super important. Let’s go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Formatting
&lt;/h2&gt;




&lt;p&gt;Dates never seem to be in the format you want them to be in. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gOLsfCUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.xkcd.com/comics/iso_8601_2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gOLsfCUR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.xkcd.com/comics/iso_8601_2x.png" width="784" height="913"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Computers interpret dates in all different formats, from unixtime to strings and timestamps, and they’re usually not friendly to each other. Here are the function prototypes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM_UNIXTIME()&lt;/code&gt; – convert a unix time date into a normal date. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TO_UNIXTIME()&lt;/code&gt; – convert a regular date format into a unix time date.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TO_DATE()&lt;/code&gt; – convert a string to a date format. Sometimes you’ll need to specify what format the string is in through the function arguments.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FORMAT_DATE()&lt;/code&gt; – convert a date into a string. This function is usually used to format dates in specific ways as strings, so the arguments are the important part.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unix time (which is also called epochs time) is kind of funky: it corresponds to the number of seconds that have elapsed since January 1st, 1970. A typical unix timestamp might look like this: &lt;code&gt;1284352323&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here’s how these different conversion functions look across major SQL dialects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Convert unix time to date format&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_from-unixtime" rel="noopener noreferrer"&gt;&lt;code&gt;FROM_UNIXTIME()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_TIMESTAMP()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date_from_unix_date" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_FROM_UNIX_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://stackoverflow.com/questions/39815425/how-to-convert-epoch-to-datetime-redshift" rel="noopener noreferrer"&gt;&lt;code&gt;TIMESTAMP 'epoch' + your_timestamp_column * INTERVAL '1 second'&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;FROM_UNIXTIME()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert date format to unix time&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_unix-timestamp" rel="noopener noreferrer"&gt;&lt;code&gt;UNIX_TIMESTAMP()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" rel="noopener noreferrer"&gt;&lt;code&gt;EXTRACT(EPOCH FROM TIMESTAMP )&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date" rel="noopener noreferrer"&gt;&lt;code&gt;UNIX_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATE_PART_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_PART(EPOCH, )&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_UNIXTIME()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert string to date format&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_str-to-date" rel="noopener noreferrer"&gt;&lt;code&gt;STR_TO_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-formatting.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#parse_date" rel="noopener noreferrer"&gt;&lt;code&gt;PARSE_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_TO_DATE_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_PARSE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert date to string format&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_FORMAT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-formatting.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_CHAR()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#format_date" rel="noopener noreferrer"&gt;&lt;code&gt;FORMAT_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_TO_CHAR.html" rel="noopener noreferrer"&gt;&lt;code&gt;TO_CHAR()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_FORMAT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here’s how we’d use these functions in Postgres, with expected inputs and outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Convert&lt;/span&gt; &lt;span class="n"&gt;unix&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TO_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="mi"&gt;1284352323&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- 2010-09-13T04:32:03.000Z&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Convert&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;unix&lt;/span&gt; &lt;span class="nb"&gt;time&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;EXTRACT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EPOCH&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="s1"&gt;'2001-02-16 20:38:40'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;-- 982355920&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Convert&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TO_DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'05 Dec 2000'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DD Mon YYYY'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- 2000-12-05&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Convert&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;TO_CHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2001-02-16 08:00:00-05'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'DD Mon YYYY'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- 16 Feb 2001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There’s a whole “language” of string formatting arguments that developers need to frantically search Google for every time they use them. Almost every single dialect follows the C strftime standard, except for Postgres. These are usually the same across &lt;code&gt;TO_DATE()&lt;/code&gt; and &lt;code&gt;FORMAT_DATE()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Date rounding
&lt;/h2&gt;




&lt;p&gt;Date rounding lets you lower the specificity of your date; this is useful for aggregations and looking at trends over time. The prototype function here is &lt;code&gt;DATE_TRUNC()&lt;/code&gt;, which truncates your date to a lower level of specificity, like month or year. Here’s how things look across dialects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Truncate date specificity&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_FORMAT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_TRUNC()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date_trunc" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_TRUNC()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATE_TRUNC.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_TRUNC()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_TRUNC()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For a more concrete example of when you’d use a date truncation function, imagine we have a table of order where each row represents an order, and each order has a date. If we want to look at order growth month over month, we’d use a truncation function in Postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Truncate&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="n"&gt;specificity&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;DATE_TRUNC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="k"&gt;month&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;count_orders&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;DATE_TRUNC()&lt;/code&gt; function grabs the month and year from the date so you can get a monthly view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Date parts
&lt;/h2&gt;




&lt;p&gt;If you have a timestamp, date part functions will pick out a particular part of that timestamp; this is useful if you want to display what day of the week a user logged in, what hour someone made an order, or aggregate event data by month to see which months of the year your website gets the most traffic. Our function prototype:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DATE_PART()&lt;/code&gt; – extract a specific part of a date, like the day of the week or year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s how it plays out across different types of SQL:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Extract specific part of date&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_extract" rel="noopener noreferrer"&gt;&lt;code&gt;EXTRACT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_PART()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#extract" rel="noopener noreferrer"&gt;&lt;code&gt;EXTRACT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATE_PART_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_PART()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;EXTRACT()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In Postgres, we can extract just the day of a user’s order using &lt;code&gt;DATE_PART()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Extract&lt;/span&gt; &lt;span class="k"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;date_part&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'day'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2001-02-16 20:38:40'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;-- 16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each SQL dialect has different approaches for how to specify data parts to extract, so be sure to check the documentation linked in the table above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences / Deltas
&lt;/h2&gt;




&lt;p&gt;If you need to calculate the duration or difference between two dates, most SQL dialects have functions for that. The popular one here is DATE_DIFF():&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DATE_DIFF()&lt;/code&gt; – get the difference between two dates in any specificity (days, years).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to get the difference between two dates in days (i.e. how many days exist between date number one and date number two) you’d use something like &lt;code&gt;DATE_DIFF(‘day’, ‘2019-01-01’, ‘2019-01-06’)&lt;/code&gt;. Weirdly, in some languages, time deltas are their own data type (see, for example, &lt;a href="https://pandas.pydata.org/pandas-docs/version/0.23.4/generated/pandas.Timedelta.html" rel="noopener noreferrer"&gt;the Pandas package in Python&lt;/a&gt;). Here’s how these functions line up:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get difference between two dates at some specificity&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_datediff" rel="noopener noreferrer"&gt;&lt;code&gt;DATEDIFF()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="http://www.sqlines.com/postgresql/how-to/datediff" rel="noopener noreferrer"&gt;Subtraction&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date_diff" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_DIFF()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATEDIFF_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATEDIFF()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_DIFF()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here’s how we’d use this in Postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;difference&lt;/span&gt; &lt;span class="k"&gt;between&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="n"&gt;dates&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-01-31'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2019-01-01'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A closely related cousin to time deltas is interval functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intervals
&lt;/h2&gt;




&lt;p&gt;Intervals let you add and subtract time from dates in SQL. This kind of function is useful for calculating rolling widows, like filtering your data for every record in the past 7 days or the past year. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DATE_ADD()&lt;/code&gt; – add an amount of time to a date.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DATE_SUB()&lt;/code&gt; – subtract an amount of time from a date.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;INTERVAL&lt;/code&gt; – use plus and minus signs to add time to a date.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PARSE_DURATION()&lt;/code&gt; – parse a formatted duration into a date. This is useful if you want to create a duration from scratch instead of subtracting two dates from each other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first two behave like normal functions, but in Postgres and Presto, using the &lt;code&gt;INTERVAL&lt;/code&gt; operator is funky. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Add time to a date&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-add" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_ADD()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/9.1/functions-datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;+ INTERVAL&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date_add" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_ADD()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATEADD()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_ADD()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subtract time from a date&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-sub" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_SUB()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/9.1/functions-datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;- INTERVAL&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date_sub" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_SUB()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_DATEADD_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATEADD()&lt;/code&gt; with negative values&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;DATE_ADD()&lt;/code&gt; with negative values&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extract date difference&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;MAKE_INTERVAL()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;PARSE_DURATION()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;INTERVAL&lt;/code&gt; operator in SQL has unusual syntax: you usually need to use the keyword, follow it with a number in single quotes, and then a date interval. In Presto, for example, you can add one day to your date by using &lt;code&gt;&amp;lt;some_date&amp;gt; + INTERVAL ‘1’ day&lt;/code&gt;. Notice how the string quotes are only around the quantity (1) and not the chosen interval (day). &lt;/p&gt;

&lt;p&gt;If we wanted to see the number of orders users have made in the past 7 days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Count&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;over&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;past&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;order_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;order_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt; &lt;span class="k"&gt;day&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here’s how we’d use the &lt;code&gt;MAKE_INTERVAL()&lt;/code&gt; function in Postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Extract&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="n"&gt;difference&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;MAKE_INTERVAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;-- { "days": 10 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Time zones
&lt;/h2&gt;




&lt;p&gt;Time zones are one of the biggest nightmares in date handling, and chances are you’re not sitting in UTC right now. Thankfully, most SQL dialects have a bunch of functions to handle TZ conversion. Our function prototypes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AT_TIMEZONE()&lt;/code&gt; – add a timezone to a date. Useful if the date doesn’t have an existing timezone attached to it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CONVERT_TZ()&lt;/code&gt; – convert between timezones. Useful if that date already has an existing timezone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Timezones also rear their ugly head when dealing with string parsing and date formatting. Here’s how these functions line up across dialects:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Add timezone to a date&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz" rel="noopener noreferrer"&gt;&lt;code&gt;CONVERT_TZ()&lt;/code&gt;&lt;/a&gt; or system settings&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT" rel="noopener noreferrer"&gt;&lt;code&gt;AT TIME ZONE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#timezone_definitions" rel="noopener noreferrer"&gt;In strings&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_AT_TIME_ZONE.html" rel="noopener noreferrer"&gt;&lt;code&gt;AT TIME ZONE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;AT TIME ZONE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Convert date to timezone or convert between timezones&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_convert-tz" rel="noopener noreferrer"&gt;&lt;code&gt;CONVERT_TZ()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT" rel="noopener noreferrer"&gt;&lt;code&gt;AT TIME ZONE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.pascallandau.com/bigquery-snippets/convert-timestamp-date-datetime-to-different-timezone/" rel="noopener noreferrer"&gt;&lt;code&gt;FORMAT_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/CONVERT_TIMEZONE.html" rel="noopener noreferrer"&gt;&lt;code&gt;CONVERT_TIMEZONE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;AT TIME ZONE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here’s how we’d add a timezone to a user’s click event or convert between timezones in Postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Add&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2001-02-16 20:38:40'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AT&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="s1"&gt;'America/Los_Angeles'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 2001-02-15T16:00:00.000Z&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Convert&lt;/span&gt; &lt;span class="k"&gt;between&lt;/span&gt; &lt;span class="n"&gt;timezones&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2001-02-15T16:00:00.000Z'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AT&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="s1"&gt;'America/Denver'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 2001-02-14T17:00:00.000Z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a few of these dialects, you use the same function (&lt;code&gt;AT TIMEZONE&lt;/code&gt;) to add a timezone to a date, as well as convert a date that already has a timezone to a different one. MySQL also has a dedicated function (&lt;code&gt;UTC_DATE()&lt;/code&gt;) for converting dates to UTC time. For more about MySQL timezones, check out this wonderful cheatsheet. &lt;/p&gt;

&lt;h2&gt;
  
  
  Current times
&lt;/h2&gt;




&lt;p&gt;The last big category of time related functionality is getting the current time. This kind of functionality is useful in similar cases as intervals, like building a rolling window. Because most of these functions return timestamps, they’re often used in conjunction with something like &lt;code&gt;DATE_TRUNC&lt;/code&gt; to pick the right intervals.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NOW()&lt;/code&gt; – gets the current timestamp at query run time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a pretty popular series of functions, so there are often a bunch of aliases. Here’s how things stack up across SQL flavors:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Function&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;BigQuery&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Redshift&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Presto&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Get the current timestamp&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_now" rel="noopener noreferrer"&gt;&lt;code&gt;NOW()&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_curtime" rel="noopener noreferrer"&gt;&lt;code&gt;CURTIME()&lt;/code&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" rel="noopener noreferrer"&gt;&lt;code&gt;CURRENT_DATE&lt;/code&gt;&lt;/a&gt; or 10 others&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions" rel="noopener noreferrer"&gt;&lt;code&gt;CURRENT_DATE()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.aws.amazon.com/redshift/latest/dg/r_CURRENT_DATE_function.html" rel="noopener noreferrer"&gt;&lt;code&gt;CURRENT_DATE&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://prestodb.io/docs/current/functions/datetime.html" rel="noopener noreferrer"&gt;&lt;code&gt;NOW()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;General best practice is to keep all of your dates and timestamps in UTC time, and display them based on the client’s timezone. If we wanted to log the time that a user logs in using Postgres, here’s what our query might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="k"&gt;Get&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;current&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="nb"&gt;timestamp&lt;/span&gt; &lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;PST&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt; &lt;span class="k"&gt;AT&lt;/span&gt; &lt;span class="nb"&gt;TIME&lt;/span&gt; &lt;span class="k"&gt;ZONE&lt;/span&gt; &lt;span class="s1"&gt;'America/Los_Angeles'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep in mind that some of these functions return a date that’s tied to the timestamp that your system is set to, which can vary pretty widely across database engines. Postgres returns UTC by default when using &lt;code&gt;CURRENT_TIMESTAMP&lt;/code&gt;, so no worries here.&lt;/p&gt;

&lt;p&gt;The truth is that as useful as some of these dialects are, scripting languages are often easier to parse dates in (&lt;a href="https://momentjs.com/" rel="noopener noreferrer"&gt;&lt;code&gt;Moment.js&lt;/code&gt;&lt;/a&gt; is a really popular one for Javascript). If you’d prefer to use more fluid programming languages like JS to work with your relational data that's already in a SQL database, give &lt;a href="https://retool.com" rel="noopener noreferrer"&gt;Retool&lt;/a&gt; a spin.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>dates</category>
      <category>formatting</category>
    </item>
  </channel>
</rss>
