React Stateless Functional Components: Nine Wins You Might Have Overlooked

React .14 introduced a simpler way to define components called stateless functional components. These components use plain JavaScript functions. Here’s the before and after in ES6:

27 lines vs 21 lines isn’t the big story… Also, note that the nested `sayHi` function on the right should admittedly be avoided for performance reasons. See comments for why.

The differences above may seem subtle at first glance, but cutting the noise is a big win.

Here’s why.

No Class Needed
Frankly, I think the drama around ES6 classes is overblown. But I do agree that plain functions are generally preferable, and eliminating the class related cruft like extends and the constructor in the example above are a nice win.

No this Keyword
As you can see above, the stateless component is just a function. Thus, all the annoying and confusing quirks with Javascript’s this keyword are avoided. The entire component becomes easier to understand without the this keyword. Just compare the click handler in each approach:

onClick={this.sayHi.bind(this)}>Say Hi</a>
onClick={sayHi}>Say Hi</a>

Note that the bind keyword isn’t necessary for the stateless component. Dumping classes eliminates the need for calling bind to pass the this context around. Given how confusing JavaScript’s this keyword is to many developers, avoiding it is a nice win.

Enforced Best Practices
Stateless functional components are useful for dumb/presentational components. Presentational components focus on the UI rather than behavior, so it’s important to avoid using state in presentational components. Instead, state should be managed by higher-level “container” components, or via Flux/Redux/etc. Stateless functional components don’t support state or lifecycle methods. This is a good thing. Why? Because it protects from laziness.

See, it’s always tempting to add state to a presentational component when you’re in a hurry. It’s a quick way to hack in a feature. Since stateless functional components don’t support local state, you can’t easily hack in some state in a moment of laziness. Thus, stateless functional components programatically enforce keeping the component pure. You’re forced to put state management where it belongs: in higher level container components.

High Signal-to-Noise Ratio
As you can see in the image above, stateless functional components require less typing. This translates less noise. As I discuss in “Writing Code for Humans”, great code maximizes the signal-to-noise ratio. The 27 line component became 21 lines, a ~20% reduction. You can go a step further on simple components. With a single line return statement, you can omit the return and parentheses. If you do this and also use ES6 destructuring on props, the result is nearly all signal:

It’s just a function that takes a parameter and returns markup. Nice. Seriously, could this feasibly be any cleaner?

Code Completion/Intellisense
If you destructure your props in ES6 as I did in the example above, then all the data you use is now specified as a simple function argument. This means you also get improved code completion/intellisense support compared to class-based components.

Bloated Components and Poor Data Structures Are Easily Spotted
We all know a function that takes a lot of parameters is a code smell. When you use ES6 destructuring with your stateless components, the argument list clearly conveys your component’s dependencies. Thus, it’s easy to spot components that need attention. In this case, you can either break up the component or rethink the data structures you’re passing around. Sometimes a long list of props can be easily resolved by passing an object instead. But if the props aren’t logically related enough to justify a single object, then it’s likely time to refactor the component into multiple separate components.

Easy to Understand
As we’ve just seen, when you see a stateless functional component, you know it’s simply a function that takes props and spits out HTML. Even if it contains a lot of markup and nested functions inside the render, it’s conceptually simple. It’s a pure function. This leads to the next big win…

Easy to Test
Since it’s a pure function, your assertions are very straightforward: Given these values for props, I expect it to return this markup. So for the example HelloWorld component, I can assert that when the render function is called with the value of ‘Cory’ for props.name, it returns a div with ‘Hi Cory’ inside.

With React’s stateless functional components, each component can be easily tested in isolation. No mocking, state manipulation, special libraries, or tricky test harnesses are needed.

Performance
Finally, stateless functional components will soon offer improved performance as well. Since there’s no state or lifecycle methods to worry about, the React team plans to avoid unnecessary checks and memory allocations in future releases. Improved performance with superior syntax, testability, and readability? Sign me up!

Summary

For all these reasons, we should strive to use stateless functional components wherever possible. Stateless components are just the latest reason why I love teaching React. React stateless functions offer the most elegant approach I’ve seen for creating a reusable component in any popular framework. Yes, even including Angular 2.

Are there other wins I’m overlooking? Downsides to consider? Chime in via the comments below.


Cory House is the author of “Building Applications with React and Redux in ES6", “Building Applications with React and Flux”, “Clean Code: Writing Code for Humans” and multiple other courses on Pluralsight. He is a Software Architect at VinSolutions and trains software developers internationally on software practices like front-end development and clean coding. Cory is a Microsoft MVP, and founder of outlierdeveloper.com.