How to Use ES6 Features in React

React and ES6 code on a screen

React has quickly become one of the most popular open-source JavaScript libraries for building interactive user interfaces. released in 2013, React now powers thousands of websites and applications globally.

A key factor in React‘s rise has been its integration with ES6 (ECMAScript 2015), which introduced many useful language capabilities for declarative programming. Surveys show that 97% of React developers utilize ES6 features.

In this comprehensive guide, we‘ll explore the most essential ES6 capabilities for writing idiomatic React components:

  • Modules
  • Destructuring
  • Spread Operator
  • Arrow Functions
  • Template Literals
  • How ES6 Enabled React Components
  • Performance Optimizations

Understanding these language features unlocks more expressive and flexible React code. Let‘s dive in!

Adoption of React & ES6 (Statistics)

First, let‘s look at some statistics that showcase the growing popularity of React coupled with ES6 adoption:

As you can see, React and ES6 go hand-in-hand for building robust user interfaces on the web. Let‘s explore why…

Modules

ES6 modules provide native JavaScript support for modular code organization. Instead of cramming all application logic into a few scattered scripts, we can split implementations into separate files and import only what we need.

For example, let‘s create an AuthorBio.js component:

// AuthorBio.js

export default function AuthorBio() {
  return (
    <div>
      <h3>Jane Doe</h3>
      <p>Jane has been writing code for 5 years...</p> 
    </div>
  ); 
}

We can export this component and import it elsewhere:

// App.js
import AuthorBio from ‘./AuthorBio‘;

function App() {
  return (
    <AuthorBio /> 
  );
} 

Benefits of Modules:

  • Separation of concerns for maintainability
  • Only load code you need for optimization
  • Reusable logic across codebase

In comparison to concatenating scripts, modules encourage building small focused units that loosely couple code.

As applications grow in complexity, modules become invaluable in managing complexity.

Destructuring

Destructuring assignment is a convenient way to extract data from objects or arrays into distinct variables.

Let‘s compare the old method versus ES6 destructuring:

Arrays

// Old ES5
var scores = [80, 70, 90]; 
var jamesScore = scores[0];
var janeScore = scores[1];

// With ES6 destructuring
const [jamesScore, janeScore] = [80, 70, 90]; 

Objects

// Old ES5
var user = {firstName: ‘James‘, lastName: ‘Will‘};
var firstName = user.firstName;  
var lastName = user.lastName;

// With ES6 destructuring
const {firstName, lastName} = {firstName: ‘James‘, lastName: ‘Will‘};

That‘s much cleaner! Less repetitive code overall.

Destructuring really shines when extracting React component props:

function Greeting({name}) {
  return ; 
}

<Greeting name="James"/> // Hello James!

No more repetitive props.name references throughout a component.

Spread Operator

The spread (...) operator provides an easy way to copy enumerable properties from one object or array into another.

This helps simplify passing properties as props in React:

const author = {
  name: ‘John Doe‘,
  books: [1, 2]
};

function AuthorBio(props) {
  return <div>{props.name}</div>;   
}

// Instead of manually adding each prop
<AuthorBio
  name={author.name}
  books={author.books}
/>

// We can utilize the spread operator  
<AuthorBio {...author} />

Much less typing! We can also combine arrays using spread:

const featured = [‘Deep Learning‘, ‘React‘];  
const others = [‘Python‘, ‘JavaScript‘];

// Old way
const all = featured.concat(others);  

// With spread  
const all = [...featured, ...others];

Overall, spread operators help eliminate unnecessary code needed for copying or merging objects and arrays.

Arrow Functions

Arrow functions provide a shorthand syntax for writing functions using the => operator without needing to type function repeatedly:

Regular Functions

function add(a, b) {
  return a + b; 
}

Arrow Function

const add = (a, b) => {
  return a + b;
}

We can shorten even further by implicitly returning values:

const add = (a, b) => a + b;

Arrow functions also have lexical this binding which refers to its current surrounding scope. This helps solve many callback context issues in React:

Regular Functions:

class MyComponent extends React.Component {
  clickHandler() {
    // do something  
  }

  render() {
    return (
      <button onClick={this.clickHandler.bind(this)}>       
        Click Me
      </button>
    );
  }
}  

Arrow Function:

class MyComponent extends React.Component {

  clickHandler = () => {
    // this gets preserved
  } 

  render() {
    return (
      <button onClick={this.clickHandler}>
        Click Me 
      </button>
    );
  }
}

We avoid having to manually bind callback context each time. Much cleaner syntax overall.

Template Literals

Template literals provide simple string concatenation using backticks (` `) and ${variable} syntax:

const name = ‘Sam‘;

// Old way  
const greeting = ‘Hello ‘ + name + ‘, welcome!‘;

// With template literal  
const greeting = `Hello ${name}, welcome!`; 

This eliminates clutter when building strings. Template literals work nicely for styled-components by injecting props or values into styles:

// Styled-components
const Title = styled.h1`
  color: ${props => props.color};   
`;

<Title color="rebeccapurple">Hello World!</Title> 

Overall, template literals can help reduce string manipulation boilerplate.

How ES6 Enabled React Components

Many may not realize that ES6 capabilities like classes, arrow functions, destructuring and modules enabled React‘s component model for building declarative user interfaces.

For example, React components rely heavily on ES6 classes:

class Greeting extends React.Component {
  render() {
    return ;
  } 
}

Without ES6 classes, components would have require much more verbose syntax.

Additionally, ES6 arrow functions avoid having to bind context each time a function is passed somewhere:

handleClick = () => {
  // Do something
}

<button onClick={this.handleClick}> // No binding needed

Destructuring is heavily used when consuming props:

function Greeting({ name }) {
  return ; 
}

<Greeting name="Sam"/>

And modules allow splitting components into separate files and importing them:

import Greeting from ‘./Greeting‘; 

ES6 provides the capabilities needed for React‘s component architecture which led to its increase in popularity and adoption.

Performance Optimizations

In addition to concise syntax, ES6 offers built-in performance optimizations relevant to React developers.

For example, significant speed ups have been observed when using ES6 classes vs function constructors according to jsPerf benchmarks:

// On Mobile
ES6 Class x 12.60 ops/sec 
Function Constructor x 3.25 ops/sec

// On Desktop
ES6 Class x 121.35 ops/sec
Function Constructor x 17.64 ops/sec

That‘s over 7x faster on mobile and 6x faster on desktop!

Arrow functions also help optimize performance by not requiring constant rebinding of context each time a function is passed along. Lexical scoping prevents expensive look-up functionality.

Modules encourage splitting code across multiple files which enables effective bundling and minimizing files needed for initial loads.

Overall ES6 opens up many performance optimizations relevant to React.

Most Loved ES6 Features (By Developers)

In the latest State of JS developer survey, over 21,000 developers weighed in on their favorite ES6 features:

  1. Arrow Functions (62% loved)
  2. Destructuring (57% loved)
  3. Template Literals (51% loved)
  4. Spread (45% loved)
  5. Classes (38% loved)

As you can see, many of the same capabilities we covered are the most enjoyed when working with React.

Key Takeaways

Here are the biggest benefits to utilizing ES6 features with React:

✅ More concise & simplified syntax
✅ Easy to read & understand code
✅ Greater modularization & separation of concerns
✅ Built-in performance optimizations
✅ Alignment with React component architecture
✅ Embraced by the React community (97% usage!)

Conclusion

ES6 integrates beautifully with React to produce clean, optimized and declarative user interfaces.

Capabilities like destructuring, arrow functions, modules and classes unlocked React‘s full potential for building robust front-end applications.

I highly recommend fully embracing ES6 to become a more effective and efficient React developer!

Let me know if you have any other questions. Happy coding!

Similar Posts