loading...

Optional chaining with React

akirautio profile image Aki Rautio Updated on ・3 min read

13.1.2020 UPDATE: Babel 7.8.0 supports optional chaining out of the box

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.


// 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 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)

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
  2. Babel with Webpack
  3. Babel with ParcelJS

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

{
  ...,
  "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 which adds support for new typescript features including optional chaining to

  2. Disabling typescript and javascript checking and installing and setting Eslint extention 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

{
  "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 or Path from Ramda.

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.

Posted on by:

akirautio profile

Aki Rautio

@akirautio

Frontend software engineer working mostly with React and Javascript. Enjoying quality code and agile operational practices.

Discussion

pic
Editor guide
 

Hey !

I don't really agree with the conclusion of your article.
Using this feature now is quite dangerous for you web performances. The way babel is transpiling the optional chaining is quite disgusting (ok, like every polyfill), but this one is not really necessary.

If you try to use it everywhere is your apps, you should notice that your bundle will swell quickly.

I wrote an article explaining why we should avoid this feature for now.

 

I would agree that performance wise it's not the best and the transpiled code looks ugly. But if this starts to cause performance issues, I would rather optimize the Babel transpiling than trying to fix it inside the application. Transpiling won't be eventually needed for most of browsers so this is a "temporary" issue.

 

I really like this. For my Gatsby project with VS Code, all I had to do was to click the TypeScript version number (which was 3.6.3) in the Status bar and choose Use Workspace Version 3.7.3. Done!

 

Oh so cool :) That's even easier way to get VSCode to work with this!