High Order & Stateless Components in React 0.14

As React continues to mature, the ways in which we write our components also takes shape. We've seen a lot of good patterns come up lately. One interesting pattern is using high order components to extend other components.

High order components are great for applying some functionality in a compositional way. This pattern ties in really well with stateless components. Here's a really simple example.

We'll have a component that displays a greeting prop.

import React, { Component } from 'react'

class App extends Component {  
  constructor(props) {
    super(props)
  }

  render() {
    return (
       <h1>{ this.props.greeting }</h1>
    )
  }
}

App.defaultProps = {  
  greeting: 'Hi'
}

export default App  

Now we'll write a high order component that can change greetings.

import React, { Component } from 'react'

const passMeProps = (WrappedComponent) => {  
  class LoggerWrap extends Component {
    render() {
      return (
        <WrappedComponent greeting={'Yo!'}/>
      )
    }
  }

  return LoggerWrap
}

export default passMeProps  

Now with a few minor changes, we can use this on our component.

import React, { Component } from 'react'  
import passMeProps from './PropsHOC'

class App extends Component {  
  constructor(props) {
    super(props)
  }

  render() {
    return (
       <h1>{ this.props.greeting }</h1>
    )
  }
}

App.defaultProps = {  
  greeting: 'Hi'
}

export default passMeProps(App)  

We include our high order component, and then wrap the App component with it before exporting.

Now our page greets us with Yo!

There are a lot more useful use cases for this pattern. Replacing Mixins, connecting your component to a store, or extending components with some 3rd party functionality.

React 0.14 introduced stateless components as a way to encourage simple components and a more compositional architecture.

Using this approach, the majority of our apps become stateless and we control their behavior by passing in props or extending them with high order components. These types of components are easy to test and reason about because given the same input, they will produce the same output.

So to write a stateless component that can be extended with our previous HOC, we can do this.

import React from 'react'  
import passMeProps from './PropsHOC'

const Test = ({greeting='Hi'}) => (  
  <h1>{greeting}</h1>
)

export default passMeProps(Test)  

Taking advantage of destructuring and default arguments from ES6, we can write a stateless component with an implied render method and default props. Then wrap this component in our high order component and we're good to go.