Front-End Insights

Stateless functional components

ProgrammingReact

In 2015, Dan Abramov wrote a great article about presentational and container components in React. I like the approach presented in his article. Basically you should divide your application components into two groups – presentational ones are only responsible for presenting data and container ones which deal with the logic. If you don’t know this concept, please read Dan’s article first! Today, I will show you how to use stateless functional components, the feature added to React in v0.14, to create these presentational components.

The previous approach

Before React v0.14 we always had to write a component by creating class and extending it from React.Component

Generally speaking, the presentational component is responsible only for showing data. That’s why it only usually has the render method. It also uses values stored in this.props directly in the JSX markup. The below example shows such a presentational component:

import React from 'react';

class EmailTable extends React.Component {
  render() {
    return (
      <table>
        <tbody>
          {this.props.emails.map((item, index) => {
            return (
              <tr key={index}>
                <td>{item.email}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    );
  }
}

export default EmailTable;

As you can see, the EmailTable component is only responsible for rendering the table with emails. The list of emails is available in this.props.

Stateless functional components – the new approach

From v0.14 of React, we can use a different syntax to create such components. The difference is that now we don’t have to declare class. We can just use the arrow function instead! What is important here is that components created this way are stateless so you can’t use the internal state of the component like you normally do in “classic” components.

Before I describe the main benefits of using this approach, let’s take a look at the same example as above but written using stateless functional components:

import React from 'react';

const EmailTable = (props) => {
  return (
    <table>
      <tbody>
        {props.emails.map((item, index) => {
          return (
            <tr key={index}>
              <td>{item.email}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

export default EmailTable;

or we can write it even better:

import React from 'react';

const EmailTable = ({ emails }) => {
  return (
    <table>
      <tbody>
        {emails.map((item, index) => {
          return (
            <tr key={index}>
              <td>{item.email}</td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

export default EmailTable;

Let’s discuss the first example. As you may have noticed, instead of creating a class, we just declared a constant EmailTable and assigned an arrow function to it. The function takes props as an argument so that we can access its props this way. The function just returns the JSX markup which uses the props argument instead of this.props. Pretty simple, right?

The second example shows that we can extract only these properties of props which we really use. We can do this by using the destructing assignment in the function declaration. The { emails } means: get the emails property from props and assign it to the new variable emails. Cool 😉

You may ask: what about propTypes??!! Well, we can still define it:

EmailTable.propTypes = {
  emails: React.PropTypes.array.isRequired
}

It works the same with defaultProps.

Why is this a better approach?

First of all, it simplifies presentational components and prevents us from being tempted to use the internal state or lifecycle methods. If you know that the component should be “dumb”, just use a stateless functional component and you will be safe 😉

For the second one, we can read in the official React documentation:

In an ideal world, many of your components would be stateless functions. In the future we plan to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

When you don’t need local state or lifecycle hooks in a component, we recommend declaring it with a function. Otherwise, we recommend to use the ES6 class syntax.

As you can see, besides recommending the use of stateless functional components, they say that we can expect that this approach will be a better choice from the performance perspective. I think it is worth using now, even if these performance optimizations are not implemented yet. Let our code be prepared!

Summary

I think that we should all try to follow the rules described by Dan Abramov in the article I wrote about at the beginning. And I think that stateless functional components are very helpful in achieving this. Apart from this, in the future, we can expect performance optimization related to these type of components so this is an additional reason to use them!

Related Post

I recommend Nozbe

Simply Get Everything Done

Get your tasks and projects done thanks to Nozbe system and apps for the Mac, Windows, Linux, Android, iPad and iPhone.

If you want to know more about Nozbe and its capabilities, please take a look at my article about this great application.