Stateless Functional Components in React 0.14

Josh Black
3 min readSep 21, 2015

The idea of defining our UI’s using declarative components has taken off recently with the emergence of React as a UI Library for not only JavaScript applications on the Web, but on Native Platforms as well.

As developers build increasingly complex and overall richer applications, the types of the components that they create have started to diverge into a number of categories. For example, the recently released Relay library makes use of a specific type of component called a Higher Order Component to define how React components tie into the system.

However, a majority of our application code will be written such that the markup returned from a component will be the same given the same exact properties. How do we classify these types of components?

History

When React was first introduced, we were able to create components with the following syntax:

var Text = React.createClass({
render: function () {
return <p>{this.props.children}</p>;
}
});
React.render(<Text>Hello World</Text>, document.body);

As React 0.13 rolled out, we became able to define components just by using ES2015 classes. For example:

class Text extends React.Component {
render() {
return <p>{this.props.children}</p>;
}
}
React.render(<Text>Hello World</Text>, document.body);

However, if the components that we defined didn’t have any internal state, then we could just skip extending the base Component class (this is changed in 0.14). Instead, we were able to represent our components as plain classes.

The (Near) Future

These stateless components may also be referred to as Pure Components, or even Dumb Components, and are meant to represent any React Component declared as a function that has no state and returns the same markup given the same props. These types of components surprisingly compose a large majority of our applications and, as a result, React 0.14 introduces the ability to write these stateless components as functions, also known as functional stateless components.

To put it more concretely:

const Text = (props) =>
<p>{props.children}</p>;
// ReactDOM is part of the introduction of React 0.14
ReactDOM.render(
<Text>Hello World</Text>,
document.querySelector('#root')
);

This pattern is designed to encourage the creation of these simple components that should comprise large portions of your apps. In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

React v0.14 Release Candidate — Ben Alpert

This pattern will also allow developers to express their UI’s using the JavaScript that they know.

In the above image, Dan Abramov is able to create these stateless component functions by leveraging language features of future versions of JavaScript, including arrow functions, destructuring, and spread. Meanwhile, this pattern still enables developers to write the JSX that we’ve all come to learn and love.

And, perhaps more importantly, is the idea that the ability to define stateless components as functions allows us to write components that are React agnostic. Ultimately, the power behind React is the new ideologies that it introduces versus its implementation.

Usage

As shown before, we can write stateless function components as a function of props that returns the appropriate markup. This doesn’t mean that you lose access to specifying the types of your props, their default value, or even context.

Continuing on with our Text example:

const Text = ({ children }) => 
<p>{children}</p>
Text.propTypes = { children: React.PropTypes.string };
Text.defaultProps = { children: 'Hello World!' };

We could even leverage default parameters in the above example, specifying the default value of our children prop as follows:

const Text = ({ children = 'Hello World!' }) =>
<p>{children}</p>

In addition, we also still get access to context in our stateless component functions. For a more involved example:

const Text = (props, context) =>
<p style={context}>props.children</p>;
Text.contextTypes = {
fontFamily: React.PropTypes.string
};
class App extends React.Component {
static childContextTypes = {
fontFamily: React.PropTypes.string
}
getChildContext() {
return {
fontFamily: 'Helvetica Neue'
};
}
render() {
return <Text>Hello World</Text>;
}
}

Some advantages to this could be global styling, as shown above, but also any form of shared global state between a tree, or sub-tree, of components.

Conclusion

React 0.14 brings forward a lot of great changes to the library, with one of these changes being the introduction of stateless function components. These stateless function components represent a surprisingly large portion of our application, with their use-case corresponding to any time we have a component that will render the same markup given the same props.

Overall, this pattern will allow developers to leverage JavaScript features to write their components in React, while also providing future optimization opportunities under the hood.

--

--

Josh Black

Building a design system for GitHub. Previously working on Carbon. Thoughts are my own.