Optional chaining with React
Tags: react, optionalchaining, javascript
Published: 2019-12-09 05:39:34

13.1.2020 UPDATE: [Babel 7.8.0 supports optional chaining out of the box](https://babeljs.io/blog/2020/01/11/7.8.0)


Optional Chaining is one of the most requested features in Javascript (and Typescript) which is no wonder since it solves a very fundamental problem; accessing the property from a dynamic deep object safely.

```javascript

// A deep structure example 
const deepObject = { 
  firstLevel: { 
    secondLevel: { 
      thirdLevel: 'value' 
    }
  }
}

// Accessing thirdLevel safely without optional chaining
const thirdLevelValue = (((deepObject || {}).firstLevel || {}).secondLevel || {}).thirdLevel

// Accessing thirdLevel safely with optional chaining
const thirdLevelValue = deepObject?.firstLevel?.secondLevel?.thirdLevel

```

The main advantage of using optional chaining is a smaller and cleaner code which makes it easier to comprehend once people get used to the syntax. 


# How to use optional chaining

Last autumn [Optional Chaining](https://tc39.es/proposal-optional-chaining/) proposal got to the Candidate stage (stage 3) which means that the specification is very close to the final version. This change resulted it to be part of Typescript 3.7 in late October 2019 and Create React App 3.3.0 at the beginning of December 2019. Also supporting tools like Prettier have already added the support.

If you are using one of these, then optional chaining should work out of the box. At the current state (December 2019) the major editors like VSCode may need a bit of configuration to handle the new syntax but I would expect this to be changed very soon. If you have some trouble, check *Configuring VSCode to handle optional chaining*-topic from below.

## Using Optional chaining with Babel

Typescript or CRA is luckily not the requirement to use optional chaining when developing with React. You can do the same with Babel __7.8.0__ and greater or with optional chaining plugin ([@babel/plugin-proposal-optional-chaining](https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining))

Since babel usually isn't used alone but as part of the toolchain, the required packages may differ from setup to setup. If you are starting to use babel, I would suggest to first follow one of these tutorials / repos:

1. [Babel setup](https://babeljs.io/en/setup)
2. [Babel with Webpack](https://dev.to/0xhjohnson/setup-react-babel-7-and-webpack-4-2168)
3. [Babel with ParcelJS](https://github.com/ARautio/optional-chaining-post)

If you have older than 7.8.0, you need to install optional chaining plugin with following command:

> npm install --save-dev @babel/plugin-proposal-optional-chaining

and adding it to .babelrc

```json
{
  ...,
  "plugins": ["@babel/plugin-proposal-optional-chaining"]
}

```

After this you should have a working setup.

## Configuring VSCode to handle optional chaining

As a default, VSCode uses typescript checking for Javascript React code and currently this isn't supporting optional chaining. There are ways to fix this: 

1. Install [ms-vscode.vscode-typescript-next extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next) which adds support for new typescript features including optional chaining to 

2. Disabling [typescript and javascript checking](https://stackoverflow.com/a/42633555) and installing and setting [Eslint extention](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to VSCode and configuring eslint to handle optional chaining.


## Configuring Eslint to handle new syntax

Eslint needs a *babel-eslint* package to understand the new syntax.

> npm install --save-dev babel-eslint

It also needs addtional configuration to _.eslintrc_

```json
{
  "parser": "babel-eslint",
  ...
}


```

# Advantages to use optional chaining compared to other options

If you have been developing with Javascript (and especially with React) for some time, you may have used some functions to handle dynamic longer paths that shouldn't fail. It may have been either internally develop a solution or a function from the external package like [Get from Lodash](https://lodash.com/docs/#get) or [Path from Ramda](https://ramdajs.com/docs/#path). 

All these functions are still as usable as they used to be but using a future native way in code makes it more future proof and reduces the amount of external code needed. Right now the optional chaining needs to be always transpiled but that won't be the case in the future. Once browsers and NodeJS start supporting it, the transpiling can be dropped without the need to change the code.