Stateless Functional Components

React v0.14 introduces stateless functional components, which should change how you write most of your React components.

From the release notes

In idiomatic React code, most of the components you write will be stateless, simply composing other components. We’re introducing a new, simpler syntax for these components where you can take props as an argument and return the element you want to render.
Code
// I use this syntax when my component fits on one line
const ListItem = (props) => <li className="list-item">{props.item.name}</li>;

// I use this when my component has no logic outside JSX
const List = ({ items }) => (
  <ul className="list">
    {items.map(item => <ListItem item={item} />)}
  </ul>
);

// I use this when the component needs logic outside JSX.
const Body = (props) => {
  let items = transformItems(props.rawItems);
  return (
    <div>
      <h1>{props.header}</h1>
      <List items={items} />
    </div>
  );
};

// This is equivalent to the last example
function Page(props, context) {
  return (
    <div>
      <Body header="My List" rawItems={props.rawItems} />
    </div>
  );
}
// propTypes and contextTypes are supported
Page.propTypes = {
  rawItems: React.PropTypes.array.isRequired,
};

React now provides a little sugar for treating functions as components. Although there are multiple components in this code snippet, they are all different ways in ES6 of writing functions. Along with ES6's arrow syntax, it's now easy to write extremely terse components!

When should you use this syntax?

Whenever you can! Specifically, whenever you don't need state or the component lifecycle methods (e.g. componentDidMount). You no longer have an excuse for components with large render methods or renderFoo instance methods.

Personally, I don't consider typing to be a bottleneck but it is a reason (laziness) why I have fewer and larger components than I'd like. This syntax gives us one less excuse.

Under the hood

React's implementation is quite simple. Inside mountComponent, React checks whether a component is instantiable. If not, React instantiates a very thin wrapper shell component.

This shell component only implements render. Notice the arguments that are passed to your function: props, context, and updater.

function StatelessComponent(Component) {
}
StatelessComponent.prototype.render = function() {
  var Component = ReactInstanceMap.get(this)._currentElement.type;
  return Component(this.props, this.context, this.updater);
};

The current implementation is simple and minimal but I expect we'll see more React support of stateless components in the near future.

In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

Exciting times ahead!

_
Read Another

Form Elements

Input elements pose an interesting situation for React's virtual DOM. How do you keep the virtual input's value in sync with the actual DOM and vice versa?

Liked this?

Subscribe

Subscribe for a range of articles from React basics to advanced topics such as performance optimization and deep dives in the React source code.